YAMLでnilをキーにしたハッシュを扱う
例は全てRuby 2.0を利用しています
nilをキーとした値を持つハッシュをYAMLに書きたい場合、
以下のように書いても"nil"という文字列として認識されます。
---
nil : nil
=> {"nil"=>"nil"}
データがnilの場合は、データ部分に何も書かないことでnilを表現できます。
---
datanil :
=> {"datanil"=>nil}
キーをnilにしたい場合、以下のように書いても、(Rubyだと)パースに失敗します。
---
: "key nil"
このような場合もYAMLの仕様では想定済みらしく、
クエッションマークを使うことで、その後ろにあるものがキーであると明示できる仕様があります。
http://yaml.org/spec/1.2/spec.html#id2772075
これを利用して、以下のようにクエッションマークの後に何も書かず、
その後コロンと値を設定することで、nilをキーとして設定できます。
---
?
: "key nil"
rubyで長い文字列をキーにする
Rubyが利用しているPsychでは、以下のように128byte以上のデータをキーにして書き出した場合、
?マークをつけて書き出します。
require 'yaml'
def mkhash(k,v)
h = {}
h[k] = v
h
end
long = "a" * 129
open("long.yml", "w") {|file|
file.write YAML.dump(mkhash(long, "long"))
}
---
? aaaaaaaaaaaaaaaaaaaaaaaaaa...aaa
: long
どうやらRubyが使っているYAMLライブラリのPsych内で、
128文字以上だったら?マークを出力するようにしているみたいです。
https://github.com/tenderlove/psych/blob/7e7ccf6fa4ee084c673d5a52888e2e18a41bfb5b/ext/psych/yaml/emitter.c#L816 https://github.com/tenderlove/psych/blob/7e7ccf6fa4ee084c673d5a52888e2e18a41bfb5b/ext/psych/yaml/emitter.c#L1168
一応YAMLの仕様としては1024文字までは?を使わなくてもいいらしいですが、何故128byteで切ってるのかは謎です。 http://yaml.org/spec/1.2/spec.html#id2792501
なお読み込む際は、クエッションマークをつけずに128byte以上のキーを指定しても問題なく読み込めます。