数値や文字列、selfといった正オブジェクトの否定の否定はTrueなのです!
...私も最初スクリプトを読んだ時は何事かと思いましたが...
pryで挙動を見ると意味を理解していただけるかと...
self #=> main !self #=> false !!self #=> true
_人人人人人人人_
> 突然のTrue <
 ̄Y^Y^Y^Y^Y^Y ̄
他のオブジェクトでも挙動は同じです
"hoge" #=> "hoge" !"hoge" #=> false !!"hoge" #=> true 1 #=> 1 !1 #=> false !!1 #=> true
逆に、負のオブジェクトは否定されるとTrue、更に否定でfalseになります。
!!false #=> false
これを生かしたのがActiveSupportのObject#blank?です。
class Object # An object is blank if it's false, empty, or a whitespace string. # For example, '', ' ', +nil+, [], and {} are all blank. # # This simplifies # # address.nil? || address.empty? # # to # # address.blank? # # @return [true, false] def blank? respond_to?(:empty?) ? !!empty? : !self end # An object is present if it's not blank. # # @return [true, false] def present? !blank? end ##中略 end
empty?メソッドが何かを返してくれれば、それを否定(#!)します。
何か存在すればfalseを返します。
falseの否定はtrue...。
empty?が無い場合はselfを否定する事でfalseを取り出します。*1
というわけで、少なくとも存在している場合はtrueを返してくれるわけです。
ついでに、モノが存在しているか確認するpresent?は!blank?と男前な実装になっています。
...このクラス、ちょっと人の事否定しすぎじゃないですかねぇ...?
追記(2016/05/03)
Chromium上でJavaScriptも同様の挙動になる事を確認しました。