[code.high.num]
class Tippy
end

mofu = Tippy.new

p !!mofu  #=> true

オブジェクトが入ってるかどうかを二重否定によってtrue/falseで返すときに使われる!!のイディオム。Rubyだとこのやり方は思わぬ形でバグを生み出してしまうかもしれない。

[code.high.num]
class Pyon
  def !@
    return Pyon.new
  end
end

usagi = Pyon.new

p !usagi     #=> #<Pyon:0x007ff3dc888a88>
p !!usagi    #=> #<Pyon:0x007ff3dc888948>
p usagi.!    #=> #<Pyon:0x007ff3dc888880>
p usagi.!.!  #=> #<Pyon:0x007ff3dc888790>

Ruby1.9移行において#!def @!; endで定義されたメソッドの呼び出しである。BasicObjectクラスに存在する#!であるが、上記の例のように再定義されていると意図せずに違うメソッドを呼び出してしまう。

ture/falseを返したいのであれば次のようにするのが賢明である。

[code.high.num:13]    
p usagi ? true : false  #=> true

最も、!@の再定義において、直感的な戻り値でない実装は避けたほうが良いかもしれない。

ちょっとビックリした最近の発見でした。



blog comments powered by Disqus

Published

20 October 2014

Tags