YAML issue with Set?

What am I doing wrong?

#!/opt/local/bin/ruby
###############################
require ‘set’
require ‘yaml’
require ‘tempfile’

def tempname(basename)
file = Tempfile.new(basename)
file.close(false)
file.path
end

class U
attr_accessor :name
def initialize(n)
@name = n
end
def ==(other)
name == other.name
end
end

set = Set.new
set.add(U.new(“one”))
set.add(U.new(“two”))

filename = tempname(“set_yaml”)
File.open(filename, “w”) {|f| YAML.dump(set, f)}

another_set = YAML.load(File.open(filename))

puts “#{set == another_set}”
###############################

The result that I get is the following:

###############################
xxx:~ piergiulianobossi$ ./set_yaml.rb
/opt/local/lib/ruby/1.8/yaml.rb:133:in load': syntax error on line 3, col -1: name: one (ArgumentError)
: true

!ruby/object:U ?
name: two
: true

’ from /opt/local/lib/ruby/1.8/yaml.rb:133:in `load’
from ./set_yaml.rb:30
###############################

Running ruby on Mac OS/X 10.4

###############################
xxx:~ piergiulianobossi$ ruby -v
ruby 1.8.5 (2006-08-25) [i686-darwin8.8.1]
###############################

Alle sabato 3 marzo 2007, thebox ha scritto:

What am I doing wrong?
As far as I can tell (I’m not a YAML expert), no. I’ve made a few
trials, and
it seems that class Hash (which is used internally by Set), has problems
with
loading / dumping when keys are custom classes. For instance, using irb
(ruby -v gives ruby 1.8.5 (2006-12-25 patchlevel 12) [i686-linux], on
gentoo)
:

require ‘yaml’
=> true
class C
end
=> nil
c=C.new
=> #<C:0xb78bd5b4>
h={c=>‘test’}
=> {#<C:0xb78bd5b4>=>“test”}
str=YAML.dump h
=> “— \n!ruby/object:C ? {}\n: test\n\n”
h1=YAML.load str
ArgumentError: syntax error on line 2, col -1: `: test


from /usr/lib/ruby/1.8/yaml.rb:133:in load' from /usr/lib/ruby/1.8/yaml.rb:133:in load’
from (irb):7

YAML can’t convert the string it just produced to a Hash. I’ve been able
(with
blind trials and using the documentation at
http://yaml4r.sourceforge.net/cookbook/, in particular the section on
ranges)
to modify the string produced by dump to make it load again. The
original
string is:


!ruby/object:C ? {}
: test

The modified one is:


? !ruby/object:C {}
: test

It seems that the problem arises from the fact that the dump puts the ?
(which, if I understand correctly, should mark a hash key) after the
type of
the object (the !ruby/object:C part), while load (correctly, I think)
wants
it before the type.

There is a bug report for this problem:
http://rubyforge.org/tracker/?group_id=426&atid=1698&func=detail&aid=8886

Stefano

On Mar 3, 11:07 am, Stefano C. [email protected] wrote:

As far as I can tell (I’m not a YAML expert), no. I’ve made a few trials, and
it seems that class Hash (which is used internally by Set), has problems with
loading / dumping when keys are custom classes. For instance, using irb
(ruby -v gives ruby 1.8.5 (2006-12-25 patchlevel 12) [i686-linux], on gentoo)
:

[…]

There is a bug report for this problem:http://rubyforge.org/tracker/?group_id=426&atid=1698&func=detail&aid=

Thanks, this makes a lot of sense. I’ll stay away from Hash-based
collection with custom classes and YAML for now.

Giuliano