2012-01-04 2 views
2

У меня возникла эта странная проблема с разницей в поведении to_yaml. Для:Strange ruby ​​to_yaml поведение

"0111".to_yaml 

возвращается:

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

В то же время это:

"0128".to_yaml 

возвращается:

"--- 0128\n" 

Как вы можете видеть, первый выход есть "" а второй - нет.

Любая идея?

Окружающая среда: MRI Ruby 1.9.2 и JRuby 1.6.5 (режим 1.9).

ответ

4

Я считаю, что Евгений прав о причине этого вопроса - кажется, что синтаксический анализатор обрабатывает строки, содержащих действительные числа в восьмеричном по-разному.

Если вам не нравится, вы можете переключиться на другой парсер YAML. В соответствии с docs имеются два парса: Syck и Psych. Первая старая и неподдерживаемая, а вторая - ее замена.

Psych Используется в последних версиях Rails и по умолчанию используется двигателем YAML в 1.9.3. Но вы можете легко использовать его в 1.9.2 и увидеть разницу:

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" 

Как вы можете видеть, нет необходимости беспокоиться о разном представлении строк в Syck до тех пор, как вы используете один и тот же двигатель на декодировать данные (в обоих случаях он возвращает исходные строки).

Если по какой-то причине вам нужно единое представление для строк в YAML вы можете переключиться на Psych (он более последователен, по крайней мере, в данном случае), но будьте осторожны, как вы могли бы получить в неприятности, пытаясь загрузить с Psych данные, которые были ранее сбрасывается с Syck.

+0

вот что мне нужно! благодаря! – agate

+0

Не знал, что парсер YAML был изменен в 1.9.3, что хорошо знать. Спасибо за совет! – Eugene

+0

Я запускаю 'ruby 1.9.3p194' на OS X (установлен через RVM), и даже если' YAML :: ENGINE.yamler' сообщает '' psych ''I_still_, вы получите вышеуказанное поведение с' '08'' и' «09''. –

0

Я могу также продублировать это. Я не уверен, что это делает, но я предполагаю, что он имеет дело с «цифрами» в строке, фактически являющимися восьмеричными числами. Или, точнее, первая восьмеричная, а вторая - нет. Если вы удалите 0, вы получите поведение от первого на обоих из них. Возможно, кто-то еще мог бы рассказать об этой теории.

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

Я просто чувствую, что это поведение очень странно. Я тестирую другую реализацию yaml как js-yaml. Кажется, они справляются с этим правильным образом ... – agate

Смежные вопросы