Ruby exceptions and YAML

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

···

--
Posted via http://www.ruby-forum.com/.

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

···

On Thursday 01 May 2008, Bill Lear wrote:

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.

Stefano Crocco wrote:

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.

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

···

On Thursday 01 May 2008, Bill Lear wrote:

--
Posted via http://www.ruby-forum.com/\.