简体   繁体   中英

Strange ruby to_yaml behavior

I got this weird problem with difference in behavior of to_yaml . For:

"0111".to_yaml

it returns:

"--- \"0111\"\n"

At the same time this:

"0128".to_yaml

returns:

"--- 0128\n"

As you can see the first output have "" but the second doesn't.

Any idea?

Environment: MRI Ruby 1.9.2 and JRuby 1.6.5 (1.9 mode).

I believe Eugene is right about the reason for these issue - seems like parser treats strings containing valid octal numbers differently.

If you don't like it you can switch to a different YAML parser. According to docs there are two parsers available: Syck and Psych . The former is old and unmaintained and the latter is its replacement.

Psych is used in latest versions of Rails and is default YAML engine in 1.9.3. But you can easily use it in 1.9.2 and see the difference:

require 'yaml'

p YAML::ENGINE.yamler      # => "syck"
# or explicitly set YAML::ENGINE.yamler = "syck" in 1.9.3
p '01'.to_yaml             # => "--- \"01\"\n"
p '08'.to_yaml             # => "--- 08\n"
p YAML.load('01'.to_yaml)  # => "01"
p YAML.load('08'.to_yaml)  # => "08"

p YAML::ENGINE.yamler = "psych"
p '01'.to_yaml             # => "--- '01'\n"
p '08'.to_yaml             # => "--- '08'\n"
p YAML.load('01'.to_yaml)  # => "01"
p YAML.load('08'.to_yaml)  # => "08"

As you can see there is no need to worry about different representation of strings in Syck as long as you're using the same engine to decode data (in both cases it returns original strings).

If for some reason you need unified representation for strings in YAML you can switch to Psych (it's more consistent at least in this case), but be careful as you might get in troubles trying to load with Psych data that was previously dumped with Syck .

I can duplicate this as well. I'm not sure what is doing it, but my first guess is that it has do with the "numbers" in the string actually being octal numbers. Or more accurately, the first being octal, and the second not. If you remove the 0, you get the behavior from the first on both of them. Perhaps somebody else could elaborate on this theory.

1.9.2p290 :002 > "0111".to_yaml
  => "--- \"0111\"\n" 
1.9.2p290 :003 > "0128".to_yaml
  => "--- 0128\n" 
1.9.2p290 :004 > "\0111".to_yaml
  => "--- \"\\t1\"\n" 
1.9.2p290 :005 > "\0128".to_yaml
  => "--- \"\\n\\\n8\"\n" 
1.9.2p290 :006 > string = "0111"
  => "0111" 
1.9.2p290 :007 > string.class
 => String 
1.9.2p290 :008 > string.to_yaml
 => "--- \"0111\"\n" 
1.9.2p290 :009 > string = "111"
 => "111" 
1.9.2p290 :010 > string.to_yaml
 => "--- \"111\"\n" 
1.9.2p290 :011 > string = "128"
 => "128" 
1.9.2p290 :012 > string.to_yaml
 => "--- \"128\"\n"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM