Forum: Ruby Bignum problems

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
47b1910084592eb77a032bc7d8d1a84e?d=identicon&s=25 Joel VanderWerf (Guest)
on 2006-03-06 06:41
(Received via mailing list)
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.lang.ruby/brow...
47b1910084592eb77a032bc7d8d1a84e?d=identicon&s=25 Joel VanderWerf (Guest)
on 2006-03-06 07:08
(Received via mailing list)
Joel VanderWerf wrote:
> /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.lang.ruby/brow...
>

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
0e303bc908294a8870899b77338ba807?d=identicon&s=25 Ville Mattila (Guest)
on 2006-03-06 07:35
(Received via mailing list)
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]
47b1910084592eb77a032bc7d8d1a84e?d=identicon&s=25 Joel VanderWerf (Guest)
on 2006-03-06 07:41
(Received via mailing list)
Ville Mattila wrote:
> 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
0e303bc908294a8870899b77338ba807?d=identicon&s=25 Ville Mattila (Guest)
on 2006-03-06 07:50
(Received via mailing list)
Joel VanderWerf <vjoel@path.berkeley.edu> writes:

> 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
---
1: 1000000000000000
=> nil
47b1910084592eb77a032bc7d8d1a84e?d=identicon&s=25 Joel VanderWerf (Guest)
on 2006-03-06 08:08
(Received via mailing list)
Joel VanderWerf wrote:
> /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.lang.ruby/brow...
>

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.
9c7f2f44463d1d4890f73e8a8229dd29?d=identicon&s=25 Caleb Tennis (Guest)
on 2006-03-06 12:56
(Received via mailing list)
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 ) )
                  {
This topic is locked and can not be replied to.