Pit Capitain
8/21/2008 10:40:00 AM
2008/8/20 Patrick Li <patrickli_2001@hotmail.com>:
> I noticed this this afternoon:
> Unmarshaling a marshaled object, makes all dynamically created methods
> private.
Patrick, that's not correct. Classes and methods aren't changed upon
marshalling.
> #Here's a class that dynamically creates the method MyPage#print()
> class MyPage
> def initialize
> MyPage.class_eval do
> def print
> puts @a
> end
> end
> end
> end
This creates a MyPage#print method for *all* MyPage instances as soon
as the first instance is created.
> #Test the class
> page = MyPage.new
Here the MyPage#print method is created.
> page.print #prints nil
As expected.
> #Marshal the object
> File.open("object.obj","w") do |f|
> Marshal.dump(page, f)
> end
Maybe you should stop Ruby at this point, see below. If you just
continue with the following code, you don't get the output you've
shown, as botp already wrote.
> #UnMarshal the object, and try printing again
> page = nil
> File.open("object.obj","r") do |f|
> page = Marshal.load(f)
> end
> page.print
>
> #gives me:
> #private method `print' called for #<MyPage:0x27af394 @a=3>
> (NoMethodError)
No, you don't get this error. See botp's example.
If you stop Ruby at the point shown above, then start a new session,
define the MyPage class as above, and then run the unmarshalling code,
then it's normal and expected that you get a NoMethodError.
Unmarshaling an object doesn't call it's class' #initialize method, so
the new method MyPage#print never is defined in the second Ruby
session. That's why you are calling the private method Kernel#print
and get the error.
Regards,
Pit