Hi Sven, Thanks for your swift and useful response as usual and yes, not only it helps a lot but teach too (as usual with your answers). I will be dealing with some bureaucratic last minute, hard deadline notification I just got yesterday from my university (following local "tradition" in public institutions of total disregard of everybody's schedule and time)... Anyway, I will be having opportunity to test your suggestions until next week, after deadline. I understand the concerns about not serializing code blocks. So far they have not been a necessity for me (as code snippets are stored as "playground trees" in the Grafoscopio notebooks), but I would like to explore this approach before considering something more complex (like Metacello/Iceberg packages for the Brea web themes). I have been using some minor modifications on objects to serialize them, mainly to store playground contents as strings, and they have worked fine until now, but I was learning all along the way and they could be just a not good practice from my file scripting times/needs. Cheers, Offray On 1/12/20 4:54 a. m., Sven Van Caekenberghe wrote:
Hi Offray,
This is a recurring question. BlockClosures are way too general and powerful to be serialised. That is why serialising BlockClosures is not supported in STON.
The code inside a block can refer to and even affect state outside the block. Furthermore the return operator is quite special as it returns from some outer context.
A subset of BlockClosures are those that are clean. These do not close over other variables, nor do they contain a return. By using their source code representation, it is possible to serialise/materialise them.
You can try this by adding the following methods:
BlockClosure>>#stonOn: stonWriter self isClean ifTrue: [ stonWriter writeObject: self listSingleton: self printString ] ifFalse: [ stonWriter error: 'Only clean blocks can be serialized' ]
BlockClosure>>#stonContainSubObjects ^ false
BlockClosure class>>#fromSton: stonReader ^ self compilerClass new source: stonReader parseListSingleton; evaluate
With these additions you can do the following:
STON fromString: (STON toString: [ :x :y | x + y ]).
Note that the actual class name depends on the Pharo version (BlockClosure in Pharo 7, FullBlockClosure in Pharo 9 and maybe soon CleanBlockClosure - Marcus is working on that last one and that would be very cool because it would say exactly what it it).
I am still not 100% convinced to add this as a standard feature to STON. Using source code fully exposes the implementation, while using the compiler can be dangerous. It also adds a dependency on source code and the compiler. But it would be good if people can experiment with this feature.
Does this help you ?
Regards,
Sven
PS: I would not modify an object just to serialise it.
On 30 Nov 2020, at 18:19, Offray Vladimir Luna Cárdenas <offray.luna@mutabit.com> wrote:
Hi,
I'm using STON for all my light storage serialization needs, like the Grafoscopio notebooks, and I also love it, as Russ stated in their mail question, and I share with him a similar request: for my Brea[1] static site generator I would like to store some BreaQuery objects as external STON files, and recover them, so I can run the queries that recreate/update the website easily. I could store them as Grafoscopio notebooks, but I don't want to make Grafoscopio a prerequisite for Brea or I could use Fuel, but I would like to store queries as a diff friendly text based format. I have considered Metacello/Iceberg packages to export code in a diff friendly format, but It maybe overkill. So I would like to see if STON can serve me here too.
[1] https://mutabit.com/repos.fossil/brea/ [2] https://mutabit.com/repos.fossil/indieweb/
So far, I'm able to serialize a code block as a string using:
BreaQuery>>asStonModified self codeBlock: self codeBlock asString ^ STON toStringPretty: self
But I'm unable to populate a block from a string. There is any way to make a string, lets say 'a + b', to become the code contents of a block, ie: [a + b ] ?
Thanks,
Offray