Outputting custom YAML types in 1.8.3

A

Aaron Schrab

I just upgraded my main development box (Debian unstable) to the new
ruby 1.8.3 packages, and noticed a change in the behaviour of custom-
defined #to_yaml methods.

Simplified example code:

require 'yaml'
class Foo
def to_yaml_type; "!example.com,2005/Foo"; end
def to_yaml( opts={} )
YAML::quick_emit( object_id, opts ) do |out|
out.map( to_yaml_type ) do |map|
map.add :foo, 'bar'
map.add :eek:ne, 2
end
end
end
end
puts( { 'a' => Foo.new }.to_yaml )

With previous versions this produced:
---
a: !example.com,2005/Foo
:foo: bar
:eek:ne: 2


The output that I now get is:
a:
:foo: bar
:eek:ne: 2


So there are a couple changes. First it's no longer outputting a line
of dashes at the beginning. Second, and more importantly, it's no
longer including the type information.

Things work fine if I just define #to_yaml_type and #to_yaml_properties
instead of #to_yaml, but I can't do that for some of my classes.

I can also get it to work if I call yaml_as for the class and use the
#taguri method generated by that as the argument when calling out.map(),
but this wouldn't be compatible with older versions.

Is this a bug, or is there something that I should be doing different?
 
W

why the lucky stiff

Aaron said:
require 'yaml'
class Foo
def to_yaml_type; "!example.com,2005/Foo"; end
def to_yaml( opts={} )
YAML::quick_emit( object_id, opts ) do |out|
out.map( to_yaml_type ) do |map|
map.add :foo, 'bar'
map.add :eek:ne, 2
end
end
end
end
puts( { 'a' => Foo.new }.to_yaml )
The out.map now takes YAML taguris. Try:

YAML::quick_emit( YAML.tagurize( to_yaml_type[1..-1] ) )

Or I would recommend switching to taguris completely in your code.
def to_yaml_type; "tag:example.com,2005:Foo"; end
The YAML syntax "!example.com,2005/Foo" is just a shortcut for a taguri.
So there are a couple changes. First it's no longer outputting a line
of dashes at the beginning. Second, and more importantly, it's no
longer including the type information.
The long string of dashes at the beginning isn't required in YAML 1.0,
so I've decided to default to headless.

_why
 
A

Aaron Schrab

At 01:07 +0900 24 Sep 2005 said:
The out.map now takes YAML taguris. Try:

YAML::quick_emit( YAML.tagurize( to_yaml_type[1..-1] ) )

Presumably you mean to use that argument when calling map on the
emitter. That works with 1.8.3, but since the YAML class included in
previous versions of ruby doesn't respond to the tagurize method it
won't work there.

So to be compatible I guess I'll just have to do something like:

yaml_type = to_yaml_type
yaml_type = YAML.tagurize(yaml_type[1..-1]) if YAML.respond_to? :tagurize
out.map(yaml_type)
Or I would recommend switching to taguris completely in your code.

That also won't work properly with older versions.
The long string of dashes at the beginning isn't required in YAML 1.0,
so I've decided to default to headless.

Yeah, I don't really care about that. I really only noticed it when
comparing the ouput to older versions because of the other issue.
 
S

Sylvain Joyeux

I don't know if it is related but the 1.8.3 from Debian unstable broke
RubyGem ... It seems that the Yaml spec built with 1.8.3 is not accepted
by previous versions.

I have now
!ruby/object:Gem::Specification

while 1.8.2 is expecting
--- !ruby/object:Gem::Specification

Sylvain
 

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,773
Messages
2,569,594
Members
45,119
Latest member
IrmaNorcro
Top