STON - a little suggestion

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

STON - a little suggestion

Carlos Lombardi
Hi,

I want to use STON to enable the backup a graph of objects pertaining to an application.
Some of the objects in this graph include, in their state, a Map that is not supported by STON.
To write these objects, I would like to write via the standard procedure all the instance variables unless that pointing to such a map, and then add a modified version of that map by hand. 

To exclude the conflicting variable is easy, I just redefine #stonAllInstVarNames at the class side as follows:
     ^self instVarNames reject: [ :theName | (theName = #references) ]
in this way, I do not need to modify the method if the state of these objects changes.
On the other hand, I found not easy to use the standard mechanism for the included instance variables. This mechanism is embedded in STONWriter>>writeObject: . I found no option but repeat the logic codified there, in the method #stonOn: of my class.

The easiest way to let STON integrate the standard mechanism to store the state of an object, with by-hand additions, is to slightly modify STONWriter>>writeObject:, adding just one line. Objects including instance variables would be written as follows:

self writeObject: anObject streamMap: [ :dictionary | 
instanceVariableNames do: [ :each | 
(anObject instVarNamed: each)
ifNotNil: [ :value | 
dictionary at: each asSymbol put: value ]
ifNil: [ 
anObject stonShouldWriteNilInstVars 
ifTrue: [ dictionary at: each asSymbol put: nil ] ] ] .
anObject stonAdditionalInfoOn: dictionary . ]

the added line is the last one, the invocation to #stonAdditionalInfoOn:. Of course, the method #stonAdditionalInfoOn: should be added to the Object class.
By redefining this method in my class, I was able to easily add the modified, STON-compatlble value, to the values handled by the STON code.

I did not need to modify the STON code to read the STON String to generate a new object.

Do you think that doing this modification to STON could be a good idea?

Cordially - Carlos


PS: I envisaged as an alternative, to allow the following method in my class

    stonOn:stonWriter
        stonWriter writeObjectAsMap: self
              do: [:mapWriter | 
                   // added code goes here
                   stonWriter writeInstVarsOf: self on: mapWriter
                   // added code goes here
              ]

To this end, the methods #writeObjectAsMap:do: and #writeInstVarsOf:on should be added to STONWriter. The method 
     writeInstVar: aSymbol  of: anObject  on: mapWriter
could be offered as well, to allow more fine-grained redefinitions of stonOn: , while keeping the ability to use the standard mechanism to store an instance variable.

I think that the option I described earlier is simpler, I include this one because maybe other people would prefere it.


Reply | Threaded
Open this post in threaded view
|

Re: STON - a little suggestion

Sven Van Caekenberghe-2
Hi Carlos,

First off: thanks for the feedback, it is very useful to discuss various real world scenarios.

> On 28 Apr 2016, at 02:33, Carlos Lombardi <[hidden email]> wrote:
>
> Hi,
>
> I want to use STON to enable the backup a graph of objects pertaining to an application.

Would it be possible to provide more details (maybe off list), I would like to have a better idea of the issue you are trying to solve.

What does that mean 'not supported by STON', why is that so ?
Why do you need to write extra information ? what is in it ? how do you deal with it afterwards ?

> Some of the objects in this graph include, in their state, a Map that is not supported by STON.
> To write these objects, I would like to write via the standard procedure all the instance variables unless that pointing to such a map, and then add a modified version of that map by hand.
>
> To exclude the conflicting variable is easy, I just redefine #stonAllInstVarNames at the class side as follows:
>      ^self instVarNames reject: [ :theName | (theName = #references) ]
> in this way, I do not need to modify the method if the state of these objects changes.

Yes, that is one extension point.

> On the other hand, I found not easy to use the standard mechanism for the included instance variables. This mechanism is embedded in STONWriter>>writeObject: . I found no option but repeat the logic codified there, in the method #stonOn: of my class.
>
> The easiest way to let STON integrate the standard mechanism to store the state of an object, with by-hand additions, is to slightly modify STONWriter>>writeObject:, adding just one line. Objects including instance variables would be written as follows:
>
> self writeObject: anObject streamMap: [ :dictionary |
> instanceVariableNames do: [ :each |
> (anObject instVarNamed: each)
> ifNotNil: [ :value |
> dictionary at: each asSymbol put: value ]
> ifNil: [
> anObject stonShouldWriteNilInstVars
> ifTrue: [ dictionary at: each asSymbol put: nil ] ] ] .
> anObject stonAdditionalInfoOn: dictionary . ]
>
> the added line is the last one, the invocation to #stonAdditionalInfoOn:. Of course, the method #stonAdditionalInfoOn: should be added to the Object class.
> By redefining this method in my class, I was able to easily add the modified, STON-compatlble value, to the values handled by the STON code.

Overwriting #stonOn: is meant to be an extension point as well.

> I did not need to modify the STON code to read the STON String to generate a new object.

How can that work ? Via additional accessors ?

Like I said, a concrete example, maybe of the STON output would be helpful.

> Do you think that doing this modification to STON could be a good idea?

Customising STON is OK, it should indeed be possible without changing the core code. But I would like to better understand your use case before really commenting.

Regards,

Sven

> Cordially - Carlos
>
>
> PS: I envisaged as an alternative, to allow the following method in my class
>
>     stonOn:stonWriter
>         stonWriter writeObjectAsMap: self
>               do: [:mapWriter |
>                    // added code goes here
>                    stonWriter writeInstVarsOf: self on: mapWriter
>                    // added code goes here
>               ]
>
> To this end, the methods #writeObjectAsMap:do: and #writeInstVarsOf:on should be added to STONWriter. The method
>      writeInstVar: aSymbol  of: anObject  on: mapWriter
> could be offered as well, to allow more fine-grained redefinitions of stonOn: , while keeping the ability to use the standard mechanism to store an instance variable.
>
> I think that the option I described earlier is simpler, I include this one because maybe other people would prefere it.
>
>