Rubyの定数はミュータブル

Rubyのおける定数とは?

Ruby以外の言語をやっていると、Rubyの定数の振る舞いは特殊に感じるかもしれない。
定数といえば、その名の通り、一度定義すると、以降変更できないことが保証されていると普通は思う。
しかし、Rubyは違う。Rubyは一度定義した定数を上書きすることができてしまう。

定数FRUITSにブルーベリーが追加されしまった。(警告出力さえ出力されない。)
もしRubyで定数をイミュータブルなものにしたい場合はfreezeメソッドを使う。

今度はランタイムエラーが発生して書き換えはできない。意図しない上書きを防ぐのに役に立つ。

なぜこのような仕様なのかというと、Rubyではクラスやモジュールの名前は定数なので、その定数が参照するオブジェクトはミュータブルである必要がある。なのでRubyでは定数を普通に定義するだけでは、ミュータブルとなり、イミュータブルにしたい場合はfreezeメソッドを使う必要がある。

ただし、freezeを使う上で注意点がある。
上のケースでは、配列そのものはfreezeしているので、pushしたりdeleteしたりなど、配列そのものの操作を行うとランタイムエラーが発生するが、配列の要素自体はfreezeされていない。つまり

とすると、要素が書き換わってしまう。

そういうときは、

要素そのものもfreezeしてやればいい。

ただし、

新たに代入はできてしまう。これは悲惨だ。

そういうときは、

上位のmoduleを作って、moduleをfreezeすればいい。

まとめ
・Rubyの定数はミュータブルであるので書き換えに注意する
・イミュータブルにするにはfreezeメソッドを使う
・配列やハッシュをfreezeする場合は配列やハッシュそのモノに加えて、要素もfreezeする
・再代入を防ぐためにはmoduleを作って、moduleをfreezeする

スポンサーリンク
スポンサーリンク
スポンサーリンク

シェアする

  • このエントリーをはてなブックマークに追加

フォローする

スポンサーリンク
スポンサーリンク