我在复杂哈希中有一些嵌套字符串,会触发“ArgumentError”异常。处理这个问题最好的方法是什么?
require 'yaml'
{
a: 'hello',
b: [{f:'hello',g:Hash.new,i:{a:'hello'}}],
c: {e:"+."}
}.to_yaml #=> `Float': invalid value for Float(): "+" (ArgumentError)
完整错误转储:
/Users/XXX/.rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/psych/scalar_scanner.rb:99:in `Float': invalid value for Float(): "+" (ArgumentError)
from /Users/XXX/.rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/psych/scalar_scanner.rb:99:in `tokenize'
from /Users/XXX/.rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/psych/visitors/yaml_tree.rb:272:in `visit_String'
from /Users/XXX/.rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/psych/visitors/yaml_tree.rb:128:in `accept'
from /Users/XXX/.rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/psych/visitors/yaml_tree.rb:324:in `block in visit_Hash'
from /Users/XXX/.rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/psych/visitors/yaml_tree.rb:322:in `each'
from /Users/XXX/.rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/psych/visitors/yaml_tree.rb:322:in `visit_Hash'
from /Users/XXX/.rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/psych/visitors/yaml_tree.rb:128:in `accept'
from /Users/XXX/.rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/psych/visitors/yaml_tree.rb:324:in `block in visit_Hash'
from /Users/XXX/.rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/psych/visitors/yaml_tree.rb:322:in `each'
from /Users/XXX/.rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/psych/visitors/yaml_tree.rb:322:in `visit_Hash'
from /Users/XXX/.rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/psych/visitors/yaml_tree.rb:128:in `accept'
from /Users/XXX/.rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/psych/visitors/yaml_tree.rb:92:in `push'
from /Users/XXX/.rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/psych.rb:244:in `dump'
from /Users/XXX/.rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/psych/core_ext.rb:14:in `psych_to_yaml'
答案 0 :(得分:1)
这似乎是捆绑心理中的一个错误。在第99行修补~/.rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/psych/scalar_scanner.rb
:
Float(string.gsub(/[,_]|\.$/, ''))
为:
Float(string.gsub(/[,_]|\.$/, '')) rescue ArgumentError
解决了这个问题。这基本上是mental gem以及Ruby 1.9捆绑版本中的内容。
如果您不想修补Ruby,使用psych-1.3.4 gem是另一种选择;请务必require 'psych'
而不是'yaml'
:
gem 'psych', '=1.3.4'
require 'psych'
{a: 'hello', b: [{f:'hello',g:Hash.new,i:{a:'hello'}}], c: {e:"0+."}}.to_yaml
# => "---\n:a: hello\n:b:\n- :f: hello\n :g: {}\n :i:\n :a: hello\n:c:\n :e: 0+.\n"
答案 1 :(得分:0)
这可以通过一个更简单的例子再现:
"+.".to_yaml
这似乎是与ruby 2.0.0捆绑的心理版本中的一个错误(以及其他版本,我敢肯定):
when FLOAT
if string == '.'
@string_cache[string] = true
string
else
Float(string.gsub(/[,_]|\.$/, ''))
end
问题在于“+”。看起来像一个有效的浮点数,如+.5。
这在Ruby 2.2.1(或可能是早期版本)中得到修复,它专门检查可能存在前导符号(+或 - )的情况:
when FLOAT
if string =~ /\A[-+]?\.\Z/
@string_cache[string] = true
string
else
Float(string.gsub(/[,_]|\.$/, ''))
end