2012-05-23 19 views
6

Powinno to być dość proste, ale wysadza w powietrze. Jakieś pomysły?BigDecimal nie może być wymuszony na BigDecimal

d = BigDecimal.new("2.0") 
YAML::load({:a => d}.to_yaml) 
TypeError: BigDecimal can't be coerced into BigDecimal 
from /Users/benjohnson/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/irb/inspector.rb:86:in `inspect' 
from /Users/benjohnson/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/irb/inspector.rb:86:in `inspect' 
from /Users/benjohnson/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/irb/inspector.rb:86:in `block in <module:IRB>' 
from /Users/benjohnson/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/irb/inspector.rb:30:in `call' 
from /Users/benjohnson/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/irb/inspector.rb:30:in `inspect_value' 
from /Users/benjohnson/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/irb/context.rb:260:in `inspect_last_value' 
from /Users/benjohnson/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/irb.rb:311:in `output_value' 
from /Users/benjohnson/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/irb.rb:160:in `block (2 levels) in eval_input' 
from /Users/benjohnson/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/irb.rb:273:in `signal_status' 
from /Users/benjohnson/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/irb.rb:156:in `block in eval_input' 
from /Users/benjohnson/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/irb/ruby-lex.rb:243:in `block (2 levels) in each_top_level_statement' 
from /Users/benjohnson/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/irb/ruby-lex.rb:229:in `loop' 
from /Users/benjohnson/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/irb/ruby-lex.rb:229:in `block in each_top_level_statement' 
from /Users/benjohnson/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/irb/ruby-lex.rb:228:in `catch' 
from /Users/benjohnson/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/irb/ruby-lex.rb:228:in `each_top_level_statement' 
from /Users/benjohnson/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/irb.rb:155:in `eval_input' 
from /Users/benjohnson/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/irb.rb:70:in `block in start' 
from /Users/benjohnson/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/irb.rb:69:in `catch' 
from /Users/benjohnson/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/irb.rb:69:in `start' 
from /Users/benjohnson/.rvm/rubies/ruby-1.9.3-p125/bin/irb:16:in `<main>'Maybe IRB bug! 
+0

Hmmm, wygląda 'to_yaml' jest zdezorientowany na BigDecimal,' BigDecimal.new ("2.0"). to_yaml' mówi '" ---! ruby ​​/ object: BigDecimal {} \ n \ n "'. –

+1

Tak. "ActiveSupport" wydaje się dodać rozszerzenie rdzenia, ale na mojej platformie otrzymuję 'BigDecimal.new (" 2.0 "). To_yaml' ->' "--- 2.0 \ n" '. Więc chociaż działa lepiej, to nadal nie konwertuje do pełnego "BigDecimal": http://apidock.com/rails/BigDecimal/to_yaml – Casper

Odpowiedz

1

Jest to błąd, który został reported i fixed.

Najlepszym rozwiązaniem byłoby uaktualnienie do najnowszej wersji Ruby (poprawka jest na poziomie poprawek od 194).

Jeśli nie możesz uaktualnić swojej wersji Ruby, możesz uzyskać poprawkę, instalując Psych gem. Jeśli to zrobisz, musisz dodać gem 'psych' przed require 'yaml' (lub dodać go do swojego Gemfile, jeśli używasz Bundlera), aby załadować kod z klejnotu zamiast ze standardowej biblioteki.

0

Oto odpowiedź Dawida, zaktualizowany do pracy w 1.9.3 dzięki this related question:

require 'yaml' 
require 'bigdecimal' 
YAML::ENGINE.yamler= 'syck' 
class BigDecimal 
    def to_yaml(opts={}) 
    YAML::quick_emit(object_id, opts) do |out| 
     out.scalar("tag:induktiv.at,2007:BigDecimal", self.to_s) 
    end 
    end 
end 
YAML.add_domain_type("induktiv.at,2007", "BigDecimal") do |type, val| 
    BigDecimal.new(val) 
end 
x = BigDecimal.new("2.0") 
puts x.to_yaml 
y = YAML.load(x.to_yaml) 
puts x == y