Ruby exceptions and YAML

B

Bill Lear

I'm confused by how YAML seems to not work with ruby exceptions. I
tried searching in vain, thus this quick post.

I would like to serialize and deserialize exception objects, but when I
deserialize a serialized exception, it does not appear to be able to
access the original message, even thought the YAML output seems to have
it. I would think that for any ruby object 'obj', the following should
hold:

obj == YAML::load(YAML::dump(obj))

but this seems to not be the case. Here is a short test script
illustrating the issue:

require 'cgi'
require 'yaml'

begin
raise "Ain't got no mojo"
rescue => ex
if YAML::load(YAML::dump(ex)) != ex
puts "NOT EQUAL"
end

puts "class=#{ex.class} message=#{ex.message}"
puts ex.message

dumped = YAML::dump(ex)
puts dumped

loaded = YAML::load(dumped)
puts "class=#{loaded.class} message=#{loaded.message}"

dumped_2 = YAML::dump(loaded)
puts dumped_2

loaded_2 = YAML::load(dumped_2)
puts "class=#{loaded_2.class} message=#{loaded_2.message}"
end

and here is a run:

% ruby --version
ruby 1.8.6 (2008-03-03 patchlevel 114) [x86_64-linux]
% ruby test_exception_dump.rb
NOT EQUAL
class=RuntimeError message=Ain't got no mojo
Ain't got no mojo
--- !ruby/exception:RuntimeError
message: Ain't got no mojo
class=RuntimeError message=RuntimeError
--- !ruby/exception:RuntimeError
message: RuntimeError
mesg: Ain't got no mojo
class=RuntimeError message=RuntimeError

Have I misunderstood something here, or is there something fundamentally
wrong with ruby YAML?


Bill
 
S

Stefano Crocco

=C2=A0I would think that for any ruby object 'obj', the following should
hold:

obj =3D=3D YAML::load(YAML::dump(obj))

but this seems to not be the case.

It depends on the =3D=3D methods for the class in question. If you try the =
same=20
using, for example, an array, you'll find that the comparison returns true.=
=20
This happens because Array redefines the =3D=3D method defined in class Obj=
ect,=20
which returns true only if the two operands are the same object. Class=20
Exception, instead, doesn't redefine it, and so the comparison between two=
=20
exceptions will always return false, unless they're the same object. This=20
means that this will return false:

RuntimeError.new('msg') =3D=3D RuntimeError.new('msg')

Since YAML.load creates a new object basing on the contents of its argument=
,=20
the returned Exception is different (according to =3D=3D) from the original.

I hope this helps

Stefano
 
B

Bill Lear

Stefano said:
It depends on the == methods for the class in question. If you try the
same
using, for example, an array, you'll find that the comparison returns
true.
This happens because Array redefines the == method defined in class
Object,
which returns true only if the two operands are the same object. Class
Exception, instead, doesn't redefine it, and so the comparison between
two
exceptions will always return false, unless they're the same object.
This
means that this will return false:

RuntimeError.new('msg') == RuntimeError.new('msg')

Since YAML.load creates a new object basing on the contents of its
argument,
the returned Exception is different (according to ==) from the original.

I hope this helps

Stefano

Thanks for the clarification, but that's really not the main issue,
although it is curious to me that '==' means "the same object" rather
than logically identical, but if that is a ruby-esque idiosyncrasy, then
I can live with it.

The main issue is why the "message" member of the exception is clearly
in the YAML dumped output, but is not loaded and available to the loaded
instance. That, to me, is a far more serious problem. Again, if I do
this:

yamilized_exception = YAML::load(YAML::dump(original_exception))

then yamlized_exception.message will be (in my case) "RuntimeError",
whereas original_exception.essage will be "Ain't got no mojo", even
though the YAML::dump(original_exception) is:

--- !ruby/exception:RuntimeError
message: Ain't got no mojo


Bill


Bill
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,072
Latest member
trafficcone

Latest Threads

Top