2013-04-26 1 views
3

"ArgumentError"예외를 트리거하는 복잡한 해시에 중첩 된 문자열이 있습니다. 이 문제를 처리하는 데있어 가장 실용적인 방법은 무엇입니까?YAML이 문자열에서 float ArgumentErrors를 던지는 이유는 무엇입니까?

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' 
+2

오류가 없습니다 2.0, 어떤 버전을 사용하고 있습니까? – nicooga

+0

'ruby 2.0.0p0 (2013-02-24 revision 39474) [x86_64-darwin12.2.1]' –

+1

아주 이상합니다. 이 구문은 1.9. * 및 2.0에서 지원됩니다. 사실 해시 구문으로 인해 1.8.7에서는 작동하지 않습니다. –

답변

1

이 번들 정신에서 버그가 수 있도록 나타납니다.

Float(string.gsub(/[,_]|\.$/, '')) 

행 : 라인에서 99 ~/.rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/psych/scalar_scanner.rb 패치

Float(string.gsub(/[,_]|\.$/, '')) rescue ArgumentError 

수정 문제. 이것은 본질적으로 심령 보석뿐만 아니라 루비 1.9 번들 버전에 있습니다.

루비를 패치하지 않으려면 psych-1.3.4 gem을 사용하는 것이 다른 옵션입니다. 간단한 예를 재현 할 수

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" 
+0

''pscych '를 require' '하는 것은 같은 오류를 던지는 것 같습니다. –

+0

그건 오타입니다. 그것은'요구 심령 '이어야합니다. ;-) –

+0

오, 그래, 그게 내가 의미했던거야. 그러나 또한 같은 오류. 방금 타입을 고치기보다는 답글을 복사하여 붙여 넣었습니다 : P –

0

이 : 단지 require 'psych' 오히려 'yaml'보다 확실

이 루비 2.0.0과 함께 번들로 정신의 버전에서 버그가 수 있도록 나타납니다
"+.".to_yaml 

(그리고 다른 버전, 나는 확실하다) :

when FLOAT 
    if string == '.' 
     @string_cache[string] = true 
     string 
    else 
     Float(string.gsub(/[,_]|\.$/, '')) 
    end 

문제는 그 "+."입니다. + 5와 같은 유효한 부동 소수점 숫자처럼 보입니다.

는 특히 선도적 인 기호가있을 수 있습니다 경우를 확인 루비 2.2.1 (또는 아마 이전 버전)에서 해결 (+ 또는 -) : 루비 재현

when FLOAT 
    if string =~ /\A[-+]?\.\Z/ 
     @string_cache[string] = true 
     string 
    else 
     Float(string.gsub(/[,_]|\.$/, '')) 
    end 
관련 문제