[YAML] Bignum problems

  • Thread starter Joel VanderWerf
  • Start date
J

Joel VanderWerf

The problems with Bignums in recent YAMLs have been discussed(*), but
does anyone have a patch that can be loaded in ruby code to get around it?

This just turned into a minor disaster for me...

$ ruby -v
ruby 1.8.4 (2005-12-24) [i686-linux]
$ ruby -r yaml -e 'y 1234567890'
--- !ruby/object:Bignum 1234567890
$ ruby -r yaml -e 'YAML.load 1234567890.to_yaml'
/usr/local/lib/ruby/1.8/yaml.rb:133:in `transfer': allocator undefined
for Bignum (TypeError)
from /usr/local/lib/ruby/1.8/yaml.rb:133:in `load'
from -e:1

(*)
http://groups.google.com/group/comp...83bffe2?q=YAML+Bignum&rnum=1#2331cd65b83bffe2
 
J

Joel VanderWerf

Joel said:
The problems with Bignums in recent YAMLs have been discussed(*), but
does anyone have a patch that can be loaded in ruby code to get around it?

This just turned into a minor disaster for me...

$ ruby -v
ruby 1.8.4 (2005-12-24) [i686-linux]
$ ruby -r yaml -e 'y 1234567890'
--- !ruby/object:Bignum 1234567890
$ ruby -r yaml -e 'YAML.load 1234567890.to_yaml'
/usr/local/lib/ruby/1.8/yaml.rb:133:in `transfer': allocator undefined
for Bignum (TypeError)
from /usr/local/lib/ruby/1.8/yaml.rb:133:in `load'
from -e:1

(*)
http://groups.google.com/group/comp...83bffe2?q=YAML+Bignum&rnum=1#2331cd65b83bffe2

Answering my own question, but it's a hack...

class Bignum
def to_yaml( opts = {} )
super.sub(/!ruby\/object:Bignum /, "")
end
end

s = 1000000000000000.to_yaml
puts s
p YAML.load(s)

OUTPUT:

--- 1000000000000000
1000000000000000
 
V

Ville Mattila

Hello,

The latest ruby cvs seems to work ok?

bash-3.00# ruby -r yaml -e 'y 1234567890000000000000'
--- 1234567890000000000000
bash-3.00# ruby -r yaml -e 'YAML.load 1234567890000000000000.to_yaml'
bash-3.00# ruby -v
ruby 1.8.4 (2006-03-04) [i386-solaris2.10]
 
J

Joel VanderWerf

Ville said:
Hello,

The latest ruby cvs seems to work ok?

bash-3.00# ruby -r yaml -e 'y 1234567890000000000000'
--- 1234567890000000000000
bash-3.00# ruby -r yaml -e 'YAML.load 1234567890000000000000.to_yaml'
bash-3.00# ruby -v
ruby 1.8.4 (2006-03-04) [i386-solaris2.10]

That's good to hear. I'd rather not have to install from cvs in all my
locations, but my workaround didn't work (see below), so maybe that's
necessary.


$ ruby
require 'yaml'

class Bignum
def to_yaml( opts = {} )
super.sub(/!ruby\/object:Bignum /, "")
end
end

h={}
h[1] = 1000000000000000
y h

-:5:in `to_yaml': private method `sub' called for
#<YAML::Syck::Scalar:0xb7b6d03c> (NoMethodError)
from /usr/local/lib/ruby/1.8/yaml/rubytypes.rb:41:in `to_yaml'
from /usr/local/lib/ruby/1.8/yaml/rubytypes.rb:40:in `to_yaml'
from /usr/local/lib/ruby/1.8/yaml/rubytypes.rb:39:in `to_yaml'
from /usr/local/lib/ruby/1.8/yaml.rb:387:in `quick_emit'
from /usr/local/lib/ruby/1.8/yaml/rubytypes.rb:38:in `to_yaml'
from /usr/local/lib/ruby/1.8/yaml.rb:117:in `dump'
from /usr/local/lib/ruby/1.8/yaml.rb:428:in `y'
from -:11
 
V

Ville Mattila

Joel VanderWerf said:
$ ruby
require 'yaml'

class Bignum
def to_yaml( opts = {} )
super.sub(/!ruby\/object:Bignum /, "")
end
end

h={}
h[1] = 1000000000000000
y h

This works fine with CVS ruby, without your special hack.
So probably the cvs is way to go.


irb(main):001:0> require 'yaml'
=> true
irb(main):002:0>
irb(main):003:0* h={}
=> {}
irb(main):004:0> h[1] = 1000000000000000
=> 1000000000000000
irb(main):005:0> y h
 
J

Joel VanderWerf

Joel said:
The problems with Bignums in recent YAMLs have been discussed(*), but
does anyone have a patch that can be loaded in ruby code to get around it?

This just turned into a minor disaster for me...

$ ruby -v
ruby 1.8.4 (2005-12-24) [i686-linux]
$ ruby -r yaml -e 'y 1234567890'
--- !ruby/object:Bignum 1234567890
$ ruby -r yaml -e 'YAML.load 1234567890.to_yaml'
/usr/local/lib/ruby/1.8/yaml.rb:133:in `transfer': allocator undefined
for Bignum (TypeError)
from /usr/local/lib/ruby/1.8/yaml.rb:133:in `load'
from -e:1

(*)
http://groups.google.com/group/comp...83bffe2?q=YAML+Bignum&rnum=1#2331cd65b83bffe2

I think this workaround actually works:

if RUBY_VERSION == "1.8.4"
class Bignum
def to_yaml( opts = {} )
YAML::quick_emit( nil, opts ) { |out|
out.scalar( nil, to_s, :plain )
}
end
end
end

...that sure beats compiling cvs for several platforms and distributing
it to users.
 
C

Caleb Tennis

Joel,

If it's helpfuly, here's the small patch we've been using in Gentoo
that I believe fixes this:

--- ext/syck/rubyext.c 27 Sep 2005 22:57:52 -0000 1.30.2.15
+++ ext/syck/rubyext.c 5 Oct 2005 10:24:16 -0000
@@ -1142,6 +1142,9 @@
}
else if ( !NIL_P( target_class ) )
{
+ if (subclass == rb_cBignum)
+ obj = rb_str2inum(val, 10);
+ else
obj = rb_obj_alloc( subclass );
if ( rb_respond_to( obj, s_yaml_initialize ) )
{
 

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,743
Messages
2,569,478
Members
44,899
Latest member
RodneyMcAu

Latest Threads

Top