Custom marshalling with YAML

Hi,

I've run into a problem when replacing "Marshal.dump" with "YAML.dump".
Some of my classes use custom marshalling, with "_dump" and "_load"
methods. With YAML these methods are not used, which breaks the
application.

YAML uses an object's "to_yaml" method if available. But that method
expects valid YAML code to be returned, unlike "_dump" that can return
just about anything. Also there doesn't seem to be anything
corresponding to "_load".
Any ideas about how I can make things compatible with both Marshal and
YAML at the same time?

/Anders

···

=====
__________________________________________________
Anders Bengtsson ndrsbngtssn@yahoo.se
Stockholm, Sweden

Höstrusk och grå moln - köp en resa till solen på Yahoo! Resor på adressen http://se.docs.yahoo.com/travel/index.html

How about this:

  module Kernel
    def to_yaml
      if respond_to? :_dump
        _dump(nil).to_yaml # TODO: _dump takes one paramter
      else
        raise
      end
    end
  end

_load is a class method!

Regards,

  Michael

···

On Mon, Jun 07, 2004 at 10:33:37PM +0900, Anders Bengtsson wrote:

Hi,

I've run into a problem when replacing "Marshal.dump" with "YAML.dump".
Some of my classes use custom marshalling, with "_dump" and "_load"
methods. With YAML these methods are not used, which breaks the
application.

YAML uses an object's "to_yaml" method if available. But that method
expects valid YAML code to be returned, unlike "_dump" that can return
just about anything. Also there doesn't seem to be anything
corresponding to "_load".
Any ideas about how I can make things compatible with both Marshal and
YAML at the same time?

How about this:

  module Kernel
    def to_yaml
      if respond_to? :_dump
        _dump(nil).to_yaml # TODO: _dump takes one paramter
      else
        raise
      end
    end
  end

That would be a nice solution. But the string returned by _dump
probably won't be valid YAML.

If I have the following class

class Foo
  def _dump(x)
    "foo"
  end

  def to_yaml
    _dump
  end
end

then YAML.dump(Foo.new) will return "foo". But that's no good, since
there's nothing to tell it that this "foo" should be de-YAMLed into a
new Foo instance.
Marshal.dump(Foo.new) will return "\004\010u:\010Foo\010foo", with all
the needed meta-data.

_load is a class method!

Yes. :slight_smile: But what's the corresponding method for YAML?

/Anders

···

--- Michael Neumann <mneumann@ntecs.de> wrote:

=====
__________________________________________________
Anders Bengtsson ndrsbngtssn@yahoo.se
Stockholm, Sweden

Höstrusk och grå moln - köp en resa till solen på Yahoo! Resor på adressen http://se.docs.yahoo.com/travel/index.html

Take a look at lib/yaml/rubytypes.rb.

There's a to_yaml_type and a YAML.add_ruby_type method.
Maybe this is a start.

Regards,

  Michael

···

On Mon, Jun 07, 2004 at 11:06:53PM +0900, Anders Bengtsson wrote:

--- Michael Neumann <mneumann@ntecs.de> wrote:
> How about this:
>
> module Kernel
> def to_yaml
> if respond_to? :_dump
> _dump(nil).to_yaml # TODO: _dump takes one paramter
> else
> raise
> end
> end
> end

That would be a nice solution. But the string returned by _dump
probably won't be valid YAML.

If I have the following class

class Foo
  def _dump(x)
    "foo"
  end

  def to_yaml
    _dump
  end
end

Thanks Michael, the code in rubytypes.rb does indeed look something
like what I'm looking for.

/Anders

···

--- Michael Neumann <mneumann@ntecs.de> wrote:

> class Foo
> def _dump(x)
> "foo"
> end
>
> def to_yaml
> _dump
> end
> end

Take a look at lib/yaml/rubytypes.rb.

There's a to_yaml_type and a YAML.add_ruby_type method.
Maybe this is a start.

=====
__________________________________________________
Anders Bengtsson ndrsbngtssn@yahoo.se
Stockholm, Sweden

Höstrusk och grå moln - köp en resa till solen på Yahoo! Resor på adressen http://se.docs.yahoo.com/travel/index.html