[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

Marshal across bindings?

jonT

4/17/2006 2:37:00 AM

Hi,

Here's a tricky one:

Goal: I want to see test whether I'm going to have problems bringing
back some marshaled data in a new Ruby instance, and take necessary
action if so. So before I save my marshaled data to disk, I'd like to
attempt loading it and see if I get an Arguement error. Makes sense? :)

I'd hoped that the following would suffice: evaluate the Marshal
dumping in the current binding, then attempt the load in another. Since
the executions should be seperate, the second binding shouldn't know
what went on in the first and I should have the equivilent of dumping
and loading in two seperate Ruby instances?

Anyway, running the below code results in f being loaded fine :(.

* Any ideas for how I can fix this?
* Any better / alternative ways of solving the problem?

Cheers,
jonT


def jim
binding
end

def bob
binding
end

jim_b=jim
bob_b=bob

puts jim_b
puts bob_b

eval("class F;end",jim_b)
eval("f=F.new",jim_b)
data=eval("Marshal.dump(f)",jim_b)

# i want this to fail with an Argument error
puts eval("Marshal.load('" + data + "')",bob_b)

5 Answers

Robert Klemme

4/17/2006 9:34:00 AM

0

jonT wrote:
> Hi,
>
> Here's a tricky one:
>
> Goal: I want to see test whether I'm going to have problems bringing
> back some marshaled data in a new Ruby instance, and take necessary
> action if so. So before I save my marshaled data to disk, I'd like to
> attempt loading it and see if I get an Arguement error. Makes sense? :)
>
> I'd hoped that the following would suffice: evaluate the Marshal
> dumping in the current binding, then attempt the load in another. Since
> the executions should be seperate, the second binding shouldn't know
> what went on in the first and I should have the equivilent of dumping
> and loading in two seperate Ruby instances?
>
> Anyway, running the below code results in f being loaded fine :(.
>
> * Any ideas for how I can fix this?
> * Any better / alternative ways of solving the problem?
>
> Cheers,
> jonT
>
>
> def jim
> binding
> end
>
> def bob
> binding
> end
>
> jim_b=jim
> bob_b=bob
>
> puts jim_b
> puts bob_b
>
> eval("class F;end",jim_b)
> eval("f=F.new",jim_b)
> data=eval("Marshal.dump(f)",jim_b)
>
> # i want this to fail with an Argument error
> puts eval("Marshal.load('" + data + "')",bob_b)

That the loading succeeds doesn't necessarily mean that f is defined
properly. You have to access f to check that, i.e. you should do any of
these:

eval "p f", bob_b
p eval("f", bob_b)

Also, I'm not sure that your code will work properly. You may have to
use data.inspect.

Kind regards

robert

ts

4/17/2006 9:48:00 AM

0

>>>>> "j" == jonT <j@Tippell.com> writes:

Well add this line

j> eval("class F;end",jim_b)

puts eval("F.new", bob_b)

j> eval("f=F.new",jim_b)
j> data=eval("Marshal.dump(f)",jim_b)

The class F is also available for bob binding : this is why it don't give
an error when you use Marshal#load in bob_b



--

Guy Decoux

jonT

4/17/2006 10:49:00 AM

0

> The class F is also available for bob binding : this is why it don't give
> an error when you use Marshal#load in bob_b

I had a flash of inspiration this morning that this would be the case.

So is it the case that class declarations (and I imangine method
declarations and so on) are all visible in the TOPLEVEL_BINDING - and
thus all Ruby bindings?

i'm thinking that the answer may involve some IPC :(

ts

4/17/2006 11:12:00 AM

0

>>>>> "j" == jonT <j@Tippell.com> writes:

j> So is it the case that class declarations (and I imangine method
j> declarations and so on) are all visible in the TOPLEVEL_BINDING - and
j> thus all Ruby bindings?

yes,


--

Guy Decoux

Ross Bamford

4/18/2006 7:26:00 PM

0

On Mon, 17 Apr 2006 11:48:53 +0100, jonT <j@Tippell.com> wrote:

>> The class F is also available for bob binding : this is why it don't
>> give
>> an error when you use Marshal#load in bob_b
>
> i'm thinking that the answer may involve some IPC :(
>

You make it sound so painful :) Don't know about performance, but this
might do the job:

class F; end

def marshal_safely?(obj)
IO.popen("ruby -e 'Marshal.load($stdin.read) rescue exit(1)'",'w') do
|rb|
rb << Marshal.dump(obj)
end
$? == 0
end

["str",{:a => :b},F.new,{:f => F.new}].each do |e|
puts "#{e.inspect} => #{marshal_safely?(e)}"
end
# "str" => true
# {:a=>:b} => true
# #<F:0xb7f7687c> => false
# {:f=>#<F:0xb7f76854>} => false

--
Ross Bamford - rosco@roscopeco.remove.co.uk