Ruby 付属の YAML モジュールは、下のような動作をする。文字列を直接 to_yaml した時だけでなく、配列やハッシュの値だった場合も同じ。
- "\r"をto_yamlしてloadするとnilになる。
- "010\r"をto_yamlしてloadすると8になる。
- "010\n"をto_yamlしてloadすると"010\n"になる。OK。
- "false\r"をto_yamlしてloadするとfalseになる。
- "false\n"をto_yamlしてloadすると"false\n"になる。OK。
- "\n\n\n\n"をto_yamlしてloadすると空文字列になる。
- "1\r\n\r\n\r\n"をto_yamlしてloadすると"1\n"になる。
to_yaml実用にならない気がしてきた。次善の策として to_yaml の前に \r\n と \r を \n に統一、\nだけの文字列は空白に変換して乗り切る。
(追記) ya2yamlを入れたらだいぶ改善した。まだ変だけど。
$ sudo gem install ya2yaml require 'rubygems' require 'ya2yaml' $KCODE = 'u' p "\r".ya2yaml
実験
の実行結果。
--- \rはnilになる。
"\r"
nil
"\n"
--- 複数の\rは1個減る。
"\r\r\r"
"\r\r"
""
--- \nは空文字列になる。
"\n"
""
"\n"
--- 複数の\nも空文字列になる。
"\n\n\n"
""
""
--- \r\nは空文字列になる。
"\r\n"
""
""
--- 複数の\r\nも空文字列になる。
"\r\n\r\n\r\n"
""
""
--- 配列でも同じ。\rはnilの要素が含まれてしまう!エラーの可能性。
["1", "\r", "2"]
["1", nil, "2"]
["1", "\n", "2"]
--- 複数の\rを含む配列。
["1", "\r\r\r", "2"]
["1", "\r\r", "2"]
["1", "", "2"]
--- ハッシュも同じ。
{:a=>"1", :x=>"\r", :b=>"2"}
{:a=>"1", :x=>nil, :b=>"2"}
{:a=>"1", :x=>"\n", :b=>"2"}
--- \nや\r\nも同じ。空文字列が配列の要素になる。
["1", "\n\n\n\n", "2"]
["1", "", "2"]
["1", "", "2"]
--- 通常は、文字列の数字をちゃんと扱える。
"1"
"1"
"1"
--- \rが付くと数値になる。なにそれ!
"1\r"
1
"1\n"
--- "010\r"は8になってしまう。8進数。
"010\r"
8
"010\n"
--- 同様に16進数。
"0x10\r"
16
"0x10\n"
--- 同様にfloat。
"0.2\r"
0.2
"0.2\n"
--- boolean。nilか文字列かみたいな判定をしてると失敗する。
["a", "false\r", "b"]
["a", false, "b"]
["a", "false\n", "b"]
--- \nは大丈夫。数字
"1\n"
"1\n"
"1\n"
--- \nは大丈夫。boolean
"true\n"
"true\n"
"true\n"
--- 文字列に\rが複数付いたら一個減る。まだマシ。
"1\r\r"
"1\r"
"1\n\n"
--- 先頭が#だと\rは消えない。
"# a\r"
"# a\r"
"# a\n"
--- 文字列の中では正しく扱える。\rの場合
"1\r2"
"1\r2"
"1\n2"
--- 文字列の中では正しく扱える。複数の\rもOK。
"1\r\r2"
"1\r\r2"
"1\n\n2"
--- 文字列中の\rは正しく扱えるが、末尾の\rは消える。
"1\r\r2\r"
"1\r\r2"
"1\n\n2\n"
--- 末尾の\nは正しく扱える。
"1\n"
"1\n"
"1\n"
--- 末尾の\nは正しく扱える。
"1\n\n"
"1\n\n"
"1\n\n"
--- 文字列中の\nは正しく扱える。
"1\n\n2\n"
"1\n\n2\n"
"1\n\n2\n"
--- \r\nは\nになる。
"1\r\n"
"1\n"
"1\n"
--- \r\nの繰り返しは1つの\nになる。
"1\r\n\r\n\r\n"
"1\n"
"1\n\n\n"