【问题标题】:BigDecimal can't be coerced into BigDecimalBigDecimal 不能被强制转换为 BigDecimal
【发布时间】:2012-05-30 06:08:18
【问题描述】:

这应该很简单,但它正在爆炸。有什么想法吗?

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!

【问题讨论】:

  • 嗯,看起来 to_yaml 对 BigDecimal 感到困惑,BigDecimal.new("2.0").to_yaml 表示 "--- !ruby/object:BigDecimal {}\n\n"
  • 是的。 ActiveSupport 似乎为此添加了核心扩展,但在我的平台上,我得到了 BigDecimal.new("2.0").to_yaml -> "--- 2.0\n"。所以虽然效果更好,但它仍然不能转换为完整的BigDecimal:apidock.com/rails/BigDecimal/to_yaml

标签: ruby serialization yaml bigdecimal


【解决方案1】:

这是reportedfixed 一直存在的错误。

最好的解决方案是升级到最新的 Ruby(修复在补丁级别 194 以上)。

如果您无法升级您的 Ruby 版本,您可以通过安装 Psych gem 来获得修复。如果你这样做,你需要在require 'yaml' 之前添加gem 'psych'(或者如果你使用的是Bundler,则将它添加到你的Gemfile)以从gem而不是标准库中加载代码..

【讨论】:

    【解决方案2】:

    是的,我遇到过一次。这是我所做的一个版本:

    YAML & BigDecimal workaround

    【讨论】:

    • 不幸的是,该解决方案不再有效。我在 ruby​​ 1.9.3
    【解决方案3】:

    这是 David 的答案,感谢this related question,已更新到 1.9.3:

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-09-05
      • 2011-05-01
      • 1970-01-01
      • 2021-12-16
      • 2013-08-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多