Why text "2e8" is treated as String by YAML on Mac but as Float on Linux in Ruby?

797 views Asked by At

For the same ruby version, the same YAML parser engine Psych (but different minor versions), but different OS (Mac vs. Linux), text "2e8" is treated as String on Mac but as Float (200000000.0) on Linux. Why? How can I fix it so they show the same behavior?

  • For Mac: Darwin 12.4.0 Darwin Kernel Version 12.4.0: root:xnu-2050.24.15~1/RELEASE_X86_64 x86_64

    require "yaml"
    RUBY_VERSION # => "1.9.3"
    YAML::ENGINE.yamler # => "psych"
    Psych::VERSION # => "1.2.2"
    
    Psych.load("2e8") # => "2e8"
    YAML.load("2e8") # => "2e8"
    YAML.load("'2e8'") # => "2e8"
    
  • For Linux: Linux 2.6.18-238.el5 #1 SMP x86_64 GNU/Linux

    require "yaml"
    RUBY_VERSION # => "1.9.3"
    YAML::ENGINE.yamler # => "psych"
    Psych::VERSION # => "1.2.1"
    
    Psych.load("2e8") # => 200000000.0
    YAML.load("2e8") # => 200000000.0
    YAML.load("'2e8'") # => "2e8"
    

I know adding quotes '2e8' will give the same behavior, but this text is part of a dump generated on Mac, which doesn't put these quotes.

2

There are 2 answers

0
Neil Slater On BEST ANSWER

It is the psych version that is causing the difference.

This is the relevant commit: https://github.com/tenderlove/psych/commit/2422a9fc3aeff3c60c6510efbf655a34218c7605

You are about two years behind latest version, so I suggest if you can to update your dependencies on the project.

How did I find this? Using github's excellent compare function: https://github.com/tenderlove/psych/compare/v1.2.1...v1.2.2

0
sawa On

As for the why part. Strictly, you have to quote all strings, but when there is no ambiguity, you can omit the quotes. And some YAML engines do that automatically. Numeral is a case where it would be ambiguously read as string or numeral if quotes were not obligatory, so such strings with pure numeral require quotes, and without quotes, they would be recognized as a numeral. The difference in your case seems to lie in whether the YAML engine recognizes the scientific notation or not. In one system, it is capable of scientific notation, so a string that can also be read as a number in scientific notation would require quotes to be recognized as a string. It would read a bare 2e8 without quotations as 2.0 X 10^8. In the other system, it is not capable, and it reads it as a string.