RubyでHashをfreezeして定数にしたけど要素にアクセスできなかった

Hashを定数として扱おうと思ったときのメモ.
Rubyの定数はミュータブルなので,freezeメソッドを使ってイミュータブルにしておく必要があります.
また,ArrayやHashなどを定数にするときには要素もfreezeしなければ,参照先オブジェクトの変化の影響を受けてしまいます.

Rubyで定数を扱う場合はfreezeするべき - Qiita
Ruby の定数やfreeze の扱い方が難しい :: by and for engineers

とかで詳しく説明されています.

コレクションを要素ごとfreezeする場合には,以下のようにmapを使うのが良さそうです.

hoge = {name: 'piyo', age: 30}.map(&:freeze).freeze

が,この定数に対して直感的に以下のようなアクセスをしようとしたらエラーになりました.

puts hoge[:name]

=> in `[]': no implicit conversion of Symbol into Integer (TypeError)

数値型を渡せと言われて気が付きましたが,そういえばmapの返り値はArrayなので,どうやらこのhogeはArrayのようです.
ということで,Hashをmapでfreezeした後もHashとして扱いたい場合には,to_hでHashに戻してあげると良さそうです.

hoge = {name: 'piyo', age: 30}.map(&:freeze).to_h.freeze
puts hoge[:name] 

=> "piyo"