[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Marshaling an object destroys dynamically created methods

Patrick Li

8/20/2008 4:18:00 AM

I noticed this this afternoon:
Unmarshaling a marshaled object, makes all dynamically created methods
private.

#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

#Test the class
page = MyPage.new
page.print #prints nil

#Marshal the object
File.open("object.obj","w") do |f|
Marshal.dump(page, f)
end

#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)
--
Posted via http://www.ruby-....

2 Answers

Mikael Høilund

8/20/2008 8:11:00 AM

0

I'm not in a position to test, but it looksnto me like the method =20
print simply isn't created on the unMarshaled object. Since the =20
methods in Kernel are included in Object as private methods, you get =20
the same error message from Object.new.print or Object.new.throw. I'm =20=

not familiar with Marshaling at all, but this may help you debug. Good =20=

luck :)

--=20
Mikael H=A9=AAilund, CTO of Meta.io

On Aug 20, 2008, at 6:17 AM, Patrick Li <patrickli_2001@hotmail.com> =20
wrote:

> I noticed this this afternoon:
> Unmarshaling a marshaled object, makes all dynamically created methods
> private.
>
> #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
>
> #Test the class
> page =3D MyPage.new
> page.print #prints nil
>
> #Marshal the object
> File.open("object.obj","w") do |f|
> Marshal.dump(page, f)
> end
>
> #UnMarshal the object, and try printing again
> page =3D nil
> File.open("object.obj","r") do |f|
> page =3D Marshal.load(f)
> end
> page.print
>
> #gives me:
> #private method `print' called for #<MyPage:0x27af394 @a=3D3>
> (NoMethodError)
> --=20
> Posted via http://www.ruby-....
>

Pit Capitain

8/21/2008 10:40:00 AM

0

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