メタプログラミングRuby 付録A よく使うイディオム その2
その1 は第9章のラストと一緒になってしまいました。
- A.2 nil ガード
- a ||= val こういう書き方よくしますね
- けど、ここの等価だと言ってるこのコードはちょっと間違ってますね。
a ||= []
が
if a != nil a = a else a = [] end
と等しいと書いてありますが
- a が false の時も代入される
- そして a が真値の時は代入がされない
はずなので、こうだと思います。
if a a = [] end
代入文自体も値を持つことを考えるとより正確にはこうですね。
a || (a = [])
代入するかどうかはローカル変数だとどうでもよさそうですが、「ミミックメソッド」を使と差がわかります。
class A def x puts "@x : #{@x.inspect}" @x end def x=(val) puts "@x <- #{val.inspect}" @x = val end end a = A.new puts "first" a.x ||= [] puts "second" a.x ||= []
実行結果
first @x : nil @x <- [] second @x : []
これは、 and や or (&& や || も)が単に論理演算子であるだけでなくて制御構文としても働く("a and b" は a が偽値の時右辺を評価しない)ことと対応しているんじゃないかと思います。