ハッシュのキーは文字列でいいのか?
Rubyの文字列は「不変でない」んだよな。ということはハッシュのキーとして使った文字列が外部で変更された場合、ハッシュから値を取り出せなくなる場合があるんだよな、とふと思って検証してみたら違っていた。
# 文字列をキーとしてハッシュを作る。 key = "foo" hash = { key=>"value" } puts key puts hash[key] # => value # キーの値を変更 puts "---" key << "o" puts key puts hash[key] # キーの値が変わっているので取り出せないはず。 puts hash["foo"] # ハッシュ内のキーも更新されているはずなので取り出せないはず。
実行結果です。
foo value --- fooo nil value
理由はRubyリファレンスマニュアル - Hashにちゃんと書かれています。
文字列をキーとして与えると、文字列をコピーし、コピーを更新不可に設定(freeze)してキーとして使用します。キーとして使われている文字列を更新しようとすると例外 TypeError が発生します。
なるほど、コピーしたものを凍結(=変更不可)して使用しているのか。ふむふむ。