From: ptkwt@... (Phil Tomson) Date: 2004-11-23T06:23:06+09:00 Subject: Re: Blocks, serailizing, and "configure, don't integrate" In article , Hugh Sasse Staff Elec Eng wrote: >The second part of this is: > >I find myself wanting blocks to be real objects before they become >procs. I'm trying to think this out but it feels like grasping wet >soap -- I can't quite get a hold on the idea. I'm thinking >something like this: > > We can't marshal procs because they carry external state. > We can't marshal blocks or lambdas for the same reason. > > When you marshal an object you give it enough information to be > re-constructed, possibly minus a few features (things that don't get > dumped). > > Can we marshal a proto-block, that when loaded in a context > causes a block to come into being in that context, without > opening ourselves up to a full eval? Then we could do something > like Block.new(Marshal.load(...)) to get a block, to pass to > proc or whatever. Possibilities that this would have include > warnings on the code within the block before/after it is > serialized/restored, and formatting as some AST so it is less > prone to casual hacking when serialized [caveats about security > through obscurity apply]. > >I'm thinking that simplifying this would enable greater utility, as >is true for all abstractions, as well as aid debugging. > Have you looked at nodewrap? http://rubystuff.org/nodewrap/ I also sometimes think that it would be useful to have a Block class and that code blocks would be instances of Block... but I suspect that would be too big of a change to Ruby at this point. Anyway, if there were a Block class it might work something like: block = { puts "my code block" } puts block.class #=> Block puts block.to_s #=> "{ puts \"my code block\"}" p = block.to_proc def useblock(&b) #could take Block object and convert to proc b.call end #Then useblock could be called in two ways: useblock block useblock { puts "use this block" } But then, maybe there wouldn't be enough difference between a Block and a Proc to make this kind of change worthwhile. Also, while in this simple case you could easily marshal 'block', other cases where a block needed to carry around more context (references to in-scope variables, etc. ) would still seem to be problematic unless you were to say that Block objects do not carry around any context, but that they 'inherit' the context in which they are loaded (the problem then being that if the Block refers to some variables that it expects to have in scope but aren't in the scope where the marshalled Block is loaded). Phil