theseion / Fuel

Fuel, the Smalltalk object serializer
https://theseion.github.io/Fuel
MIT License
26 stars 12 forks source link

[Bug]: Materializing InstVar after Move to Different Trait #287

Closed seandenigris closed 8 months ago

seandenigris commented 9 months ago

In my LivingLibrary project, there is a LlAuthoredWork class which has a properties instVar. @ralfbarkow is trying to migrate his data to a newer version, but this instVar just will not seem to materialize.

The only obvious code change which would affect this instVar is that the class previously directly used Magritte's MATPropertyOwner trait (excerpt from class definition here):

Object subclass: #LlAuthoredWork
    uses: LlTLibraryItem + (MATPropertyOwner - {#editLepiterPageDescription}) + MpTAlphabetizable + QuTTranscriptable

and now uses MATPropertyOwner via a subtrait, DbTDomainObject, which inherits from MATPropertyOwner:

Object subclass: #LlAuthoredWork
    uses: LlTLibraryItem + (DbTDomainObject - {#editLepiterPageDescription}) + MpTAlphabetizable + QuTTranscriptable

I did an experiment which confirmed that the data is still there, just not getting into the correct instVar:

Screenshot 2023-10-24 at 5 48 24 AM
theseion commented 9 months ago

I wrote a test to try and replicate your issue (in Pharo 12 with the latest version of Fuel):

testTraitInheritance
    | class instance result |
    class := self classFactory make: [ :builder |
        builder
            traitComposition: FLNormalStatefulTrait;
            name: #FLTraitInheritanceTestClass ].
    instance := class new.
    instance properties
        at: #key
        put: 'value'.

    self serialize: instance.
    instance := nil.
    self classFactory delete: class.
    class := self classFactory make: [ :builder |
        builder
            traitComposition: FLStatelessSupertrait;
            name: #FLTraitInheritanceTestClass ].

    result := self materialized.
    self assert: (result properties includesKey: #key)
Trait << #FLNormalStatefulTrait
    slots: { #properties };
    tag: '';
    package: 'Fuel-Core-Tests'
Trait << #FLStatelessSupertrait
    traits: {FLNormalStatefulTrait};
    slots: {};
    tag: '';
    package: 'Fuel-Core-Tests'

The test first creates a class that directly uses the stateful trait and then materializes the instance using another class where the stateful trait is a subtrait. The test works as expected. This could be related to the version of Fuel you're using.

seandenigris commented 8 months ago

Okay, thanks for that impressive effort! Let's mark closed for now unless we see it again with latest Fuel