From: Rick DeNatale Date: 2009-03-03T22:00:10+09:00 Subject: Re: Marshal.load does not create new instances? --00163630f2bf7b7ea704643688e7 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit On Tue, Mar 3, 2009 at 2:29 AM, Robert Klemme wrote: > On 03.03.2009 04:38, Mike Gold wrote: > >> Robert Klemme wrote: >> >>> I believe he wants to evolve the class and be able to load data >>> written with an older (or just different) version of the class. And >>> now Ian hits the usual problems of schema migration. >>> >>> Ian, you should be aware of one thing: class definitions are not >>> serialized - no programming language that I know does this. >>> >> >> .. except languages in which code and data are equivalent! >> >> Sorry, I had to bite. >> > > Ouch! ;-) > > This is a great example of the power of code-data equivalence. If you >> store the definitions, things will just work. >> > > Well, *certain* things will just work. But you'll trade this for different > issues. For example, all of a sudden you can have different implementations > of the same class coexist. I wouldn't say that one or the other solution is > necessarily easier. They both do not change the complexity of the > underlying problem (evolution of code with data artifacts belonging to > different versions). Both approaches (i.e. storing code and not storing > code) make certain things easy and other things hard. Ruby has some subtleties in this area when compared to other OO languages. Mike Gold introduced the idea that this was a problem in dealing with schema migration. To me this implies dealing with layout changes to the object. This is a problem in most languages like Java, C++ and Smalltalk where classes, along with whatever other language specific roles they play, act as a template for understanding which instance variable goes where in a reified instance. This means that if you marshal an object then match it up to a class with the same template, you run into the danger of misinterpreting the state of the object. In systems written in these languages, you might be able to get away with two different versions of a Class which have the same instance layout template but vary in method implementations, or even have slightly different method repertoires. Ruby falls into the class of languages where classes DON'T act as templates, instead instance variables are dynamically bound to each instance with a run-time lookup used to map instance variable names to location. So the OP's case shows that you can marshal Ruby objects and the 'schema' is carried with each object. It's just that accessor methods don't go along. As it turns out, the MagLev project is trying to figure out how to deal with a similar problem right now. In Gemstone Smalltalk, which is the code base on which MagLev is being built, classes and instances are all held in a shared persistant store. When a process changes a class, and commits a transaction, other processes see the change when the results of the transaction become visible to them (i.e. when they start up, or commit or abort a transaction of their own). Now, this was apparently the same model they were planning to follow for MagLev. However, we had some discussions in the beta-testers forum about how this might or might not work with many Ruby programs because the Ruby execution model builds up classes at run time from a known initial state, and classes change as the code executes, either through 'normal' class method definition (both of which are execution time events in Ruby) or through various levels of metaprogramming sophistication. Because Ruby classes get built incrementally at run-time, the order of execution can be important, so starting with a persisted initial set of class definitions can be problematic at times. So currently MagLev allows independent control over whether or not a transaction commit persists changes to class definitions. A process needs to explicitly indicate that it want's to put class definition changes into the state to be committed before committing. We'll see how this evolves. -- Rick DeNatale Blog: http://talklikeaduck.denhaven2.com/ Twitter: http://twitter.com/RickDeNatale WWR: http://www.workingwithrails.com/person/9021-rick-denatale LinkedIn: http://www.linkedin.com/in/rickdenatale --00163630f2bf7b7ea704643688e7--