Ruby は標準添付の yaml で、Perl は YAML::Syck にします。でもって、Syck のオプションを
$YAML::Syck::ImplicitTyping = 1; $YAML::Syck::SingleQuote = 1;
にするとたぶん互換になるみたいです。ImplicitTyping は POD にも「こうすると互換になるよ」って書いてあるやつです。SingleQuote は 8 進数みたいな文字列 (/0[0-7]+/) をよみかきするときに必要になります。
use strict; use warnings; use Data::Dumper; sub p { print Dumper shift } use YAML::Syck; p YAML::Syck::Load(YAML::Syck::Dump({foo=>"0100"})); p YAML::Syck::Dump({foo=>"0100"}); $VAR1 = { 'foo' => '0100' }; $VAR1 = '--- foo: 0100 '; $YAML::Syck::ImplicitTyping = 1; $YAML::Syck::SingleQuote = 1; p YAML::Syck::Load(YAML::Syck::Dump({foo=>"0100"})); p YAML::Syck::Dump({foo=>"0100"}); $VAR1 = { 'foo' => '0100' }; $VAR1 = '--- "foo": \'0100\' '; $YAML::Syck::ImplicitTyping = 1; $YAML::Syck::SingleQuote = 0; p YAML::Syck::Load(YAML::Syck::Dump({foo=>"0100"})); p YAML::Syck::Dump({foo=>"0100"}); $VAR1 = { 'foo' => 64 }; $VAR1 = '--- foo: 0100 '; use YAML; p YAML::Load(YAML::Dump({foo=>"0100"})); p YAML::Dump({foo=>"0100"}); $VAR1 = { 'foo' => '0100' }; $VAR1 = '--- foo: 0100 '; use YAML::XS; p YAML::XS::Load(YAML::XS::Dump({foo=>"0100"})); p YAML::XS::Dump({foo=>"0100"}); $VAR1 = { 'foo' => '0100' }; $VAR1 = '--- foo: 0100 ';
Ruby の YAML.load の挙動は YAML::Syck の $YAML::Syck::ImplicitTyping = 1; のときの挙動と一緒です。すなわちクオートしない /0[0-7]+/ は8進数の数値になります。YAML.dump は数値っぽい文字列を自動でクオートします。
require "yaml" p YAML.load(<<EOS) #=> {"foo"=>64} --- foo: 0100 EOS p YAML.load(<<EOS) #=> {"foo"=>"0100"} --- foo: "0100" EOS puts YAML.dump({"foo" => "0100"}) # --- # foo: "0100" # puts YAML.dump({"foo" => "aaa"}) # --- # foo: aaaa
ポイントは結局のところ
みたいですね。あと、Perl しか使わない場合でも、$YAML::Syck::ImplicitTyping = 1 で使うときは必ず $YAML::Syck::SingleQuote = 1; も指定しないとデータがこわれてしまうみたいです。
Perl については調べきれてないかもしれないです (Syck 以外でもクオートできるのかな……)。もしかするともっといい方法があったりするのかもしれない……