freezeできない「既存の定数」って何? - Effective Ruby
『Effective Ruby』を読んでのメモ。前回はこちら。
今日は2章の項目10まで読みすすめました。1章の続きを復習します。
項目4 定数がミュータブルなことに注意しよう
Rubyでは定数は書き換えられる値なので、書き換えられて困る値はfreezeしようという話。
配列の定数を使う場合は、配列自体と、配列の要素を両方freezeする必要がある。
疑問点
p.11の次の文章が、よく分からなかった。
定数をフリーズすれば、目立たず、追跡しにくいバグを例外に変えることができる。これは、明らかに大きなことだ。しかし、これではまだ十分ではない。定数が参照するオブジェクトをフリーズしても、既存の定数に新しい値を代入すれば、問題が起きる。
上の文章の「既存の定数」が何を意味しているのかが分からない。既存?
このくだりでは、次のようなサンプルコードで、「既存の定数」であるところのTIMEOUTという値に対して値を代入できてしまうことが示される。
irb(main):001:0> TIMEOUT=5 => 5 irb(main):002:0> TIMEOUT += 5 (irb):2: warning: already initialized constant TIMEOUT (irb):1: warning: previous definition of TIMEOUT was here => 10
ためしに定数TIMEOUT自体をfreezeするも、値を代入できてしまう。
irb(main):003:0> TIMEOUT.freeze => 10 irb(main):004:0> TIMEOUT += 5 (irb):4: warning: already initialized constant TIMEOUT (irb):2: warning: previous definition of TIMEOUT was here => 15
定数TIMEOUTは直接freezeできない(しても意味がない?)ということは分かる。
本文では、moduleの中にTIMEOUTを定義して、module自体をfreezeするという対処法が述べられている。
項目5 実行時の警告に注意しよう
Rubyは、構文解析フェーズ(本文ではコンパイル時と呼んでいる)と実行フェーズの2つでコードを操作する。処理系のオプションを活用すると、それぞれのフェーズで別の種類の警告を表示できる。
- コンパイル時の警告の出し方
- 実行時の警告の出し方
-wオプションをつけることと、VERBOSE変数を使うことは、排他ではない。両方やれというのが筆者の主張。
警告を活用してコードを修正しよう、Rubyにコードの意図を推測させるのはやめよう、という話だった。
今日はここまで。第1章は終了。
- 作者: Peter J. Jones,arton,長尾高弘
- 出版社/メーカー: 翔泳社
- 発売日: 2015/01/09
- メディア: 大型本
- この商品を含むブログ (13件) を見る