16 Aug, 2009, flumpy wrote in the 1st comment:
Votes: 0
I'm mainly just interested, but is Ruby able to persist its metaclass data at all?

For example, if I define a class and add a closure to it, then persist it and deserialise it, will the class still have the closure attached?

I don't know the ruby syntax but heres the code in groovy which is similar:
def myObject = new MyObject()

myObject.metaClass.get = {.. my get closure ..}
myObject.get "axe"

myObject = xstream.parseXML(xstream.toXML(myObject)) // or something like this..

myObject.get "axe" // in groovy will throw methodnotfoundexception
16 Aug, 2009, Runter wrote in the 2nd comment:
Votes: 0
I'm not sure. But I'll look into it if nobody answers the question before I get around to it. :)
16 Aug, 2009, flumpy wrote in the 3rd comment:
Votes: 0
Think I've found the answer, and it's basically "no":

http://rubyquiz.com/quiz38.html
16 Aug, 2009, Chris Bailey wrote in the 4th comment:
Votes: 0
I'm trying to dig around and figure out if 1.9 supports it with lambda's or procs =(

EDIT: It doesn't look like it…quoted from random website I found -

You cannot marshal a Lambda or Proc. This is because both of them are considered closures which means they close around the memory on which they were defined and can reference it. (In order to marshal them you'd have to Marshal all of the memory they could access at the time they were created.)

As Gaius pointed out though, you can use ruby2ruby to get a hold of the string of the program. That is, you can marshal the string that represents the ruby code and then reevaluate it later
16 Aug, 2009, flumpy wrote in the 5th comment:
Votes: 0
Chris Bailey said:
I'm trying to dig around and figure out if 1.9 supports it with lambda's or procs =(

EDIT: It doesn't look like it…quoted from random website I found -

You cannot marshal a Lambda or Proc. This is because both of them are considered closures which means they close around the memory on which they were defined and can reference it. (In order to marshal them you'd have to Marshal all of the memory they could access at the time they were created.)

As Gaius pointed out though, you can use ruby2ruby to get a hold of the string of the program. That is, you can marshal the string that represents the ruby code and then reevaluate it later


FYI I just marshalled a closure with groovy well enough, at least with xstream.

I really want to marshall the metaClass tho, guess its not possible in either because the metaclass holds procs in ruby, and other wierd sorts of data structures in groovy.

This is a bit of a shame really, because it would be cool to assign procs to the Ruby metaclass, and have that object persisted (as part of a players inventory say). That way I could script stuff on the fly (a quick object here or there to while away my time), stick it in the game and have it persisted with all its meta methods.

Oh well.

I won't go into it more in groovy, because this isnt really the place. Suffice to say I can get around the transient metaclass with a map of closures, but its not the same :(
16 Aug, 2009, flumpy wrote in the 6th comment:
Votes: 0
As a bit more of an on topic post, don't you think this is a bit of an oversight on the ruby devs parts?

I mean, if I'd bothered to spend all my time writing metadata for a class and then wanted to serialise it in a session or something, I'd damn well expect the de-martialling to include my flippin' metadata :(

..and before you flarp on, no, evaluation is not a good enough "workaround" :devil:
16 Aug, 2009, Chris Bailey wrote in the 7th comment:
Votes: 0
flumpy said:
and before you flarp on, no, evaluation is not a good enough "workaround"

Well then I have no comment! Hehe, I do agree that it should be included but I'm not so sure that it's an oversight. I will continue looking into it and see if I can find out "why" it isn't included, they usually have pretty good reasons.
16 Aug, 2009, David Haley wrote in the 8th comment:
Votes: 0
Chris Bailey said:
they usually have pretty good reasons.

"It's hard", "we don't feel like it", "we haven't really needed it yet"…? :smile: Maybe more realistically, "the internal implementation makes it nastily difficult but in principle it's possible".
Sort of like why it took so long to get at least decently efficient? :wink:

I believe that for Lua, the Pluto persistence library can serialize closures.

The random website Chris found said:
You cannot marshal a Lambda or Proc. This is because both of them are considered closures which means they close around the memory on which they were defined and can reference it. (In order to marshal them you'd have to Marshal all of the memory they could access at the time they were created.)

I'm not sure I buy this argument from a theoretical standpoint. You'd have to marshal variables that the closure actually accessed, and anything accessible from there, but that's a far cry from saying all the memory that could possibly be accessed.
16 Aug, 2009, flumpy wrote in the 9th comment:
Votes: 0
David Haley said:
Sort of like why it took so long to get at least decently efficient? :wink:


Rowwr, ooh thems are sharp claws kitty ;D
16 Aug, 2009, David Haley wrote in the 10th comment:
Votes: 0
Sorry :devil:
16 Aug, 2009, flumpy wrote in the 11th comment:
Votes: 0
David Haley said:
Sorry :devil:


oh don't be sorry ;D I agree.

The thing is, ruby is a comparatively young language compared to most, so it's perfectly natural not to have got all the gremlins out the works yet.

I hope its not going to stay "fundamentally broken" though because it would be something I would expect to work (that goes for groovy metaclasses too).
16 Aug, 2009, Chris Bailey wrote in the 12th comment:
Votes: 0
=( You guys are mean, hehe.
16 Aug, 2009, Tyche wrote in the 13th comment:
Votes: 0
flumpy said:
As a bit more of an on topic post, don't you think this is a bit of an oversight on the ruby devs parts?


No.
16 Aug, 2009, Tyche wrote in the 14th comment:
Votes: 0
David Haley said:
The random website Chris found said:
You cannot marshal a Lambda or Proc. This is because both of them are considered closures which means they close around the memory on which they were defined and can reference it. (In order to marshal them you'd have to Marshal all of the memory they could access at the time they were created.)

I'm not sure I buy this argument from a theoretical standpoint. You'd have to marshal variables that the closure actually accessed, and anything accessible from there, but that's a far cry from saying all the memory that could possibly be accessed.


Yes, a lambda must be able to access all the memory that they could access at the time they were created, which is theoretically ALL the memory.
16 Aug, 2009, David Haley wrote in the 15th comment:
Votes: 0
Most mysterious, then, that the Lua people do it without serializing the entire memory space. Hmm…

Given that you don't access memory by address but by variables, one wonders how exactly one is supposed to get access to the entire memory space, unless the entire address space is directly accessible, and accessed by the procedure, in which case naturally you would want to serialize it all!
17 Aug, 2009, Tyche wrote in the 16th comment:
Votes: 0
David Haley said:
Most mysterious, then, that the Lua people do it without serializing the entire memory space. Hmm…

Given that you don't access memory by address but by variables, one wonders how exactly one is supposed to get access to the entire memory space, unless the entire address space is directly accessible, and accessed by the procedure, in which case naturally you would want to serialize it all!


No. Invalid context.
17 Aug, 2009, flumpy wrote in the 17th comment:
Votes: 0
Tyche said:
No. Invalid context.


Care to explain?
17 Aug, 2009, David Haley wrote in the 18th comment:
Votes: 0
Tyche does not explain, Tyche simply states his magnificence for mortals to bow and accept. (Or is that Chuck Norris? Hmm…)
17 Aug, 2009, Tyche wrote in the 19th comment:
Votes: 0
flumpy said:
Tyche said:
No. Invalid context.


Care to explain?


It means I'm done trying to explain the what the webpage is saying and have no interest in what the poster wants to argue.
17 Aug, 2009, Tyche wrote in the 20th comment:
Votes: 0
A Ruby install comes with three libraries for serialization, Marshal, PStore, and YAML.
None of them can serialize closures, as well as many other objects like IO and Singleton.
If you want to serialize one of these objects, you have to write your own serialization
routines.

A closure in Ruby is both the code block and the binding. The binding is the execution
context which includes all the variables, self, iterators, and methods that can be
accessed at that point. It should be obvious that writing a generic serialization routine
that walks the execution context is probably not going to be trivial. It's certainly
possible for one to write a custom routine that serializes a subset of execution context
that would be serviceable for particular procs. Then we have the code block. For Ruby
the use of the 4 or 5 techniques in the code quiz illustrate the different ways to do it.

And then I discover that Groovy can't serialize closures either.
So I wonder exactly what it really is you wish to accomplish with Ruby.
0.0/33