【一人 Ruby Advent Calendar 2017】Ruby における真と偽【6日目】
一人 Ruby Advent Calendar 2017 6日目の記事になります。
Ruby おける真と偽
Ruby では『false
もしくは nil
』は偽、『それ以外以外の全てのオブジェクト』は真になります。
なので、0
という数値も Ruby では真となります。
result = if 0 42 end p result # => 42
他の言語では 0
が偽として扱われることも多いので Ruby を使う場合は注意する必要があります。
Ruby でビット演算する場合の注意
さて、例えば C++ で『任意のビットが立っているかどうか』を判定する為に &
演算子を使うことがあります。
// n に対して 0b0001 ビットが立っているかどうか判定する if( n & 0b0001 ){ std::cout << "ok" << std::endl; }
これは n & 0b0001
の結果が 0
であれば『n
の 0b0001
ビットが立っていない』と判定できるためです。
これをそのまま Ruby で書くと以下のようになると思います。
if n & 0b0001 "OK" end
ですが、上記のコードでは正しく動作しません。
なぜなら『C++ では 0
が偽』として扱われますが、『Ruby では 0
が真』として扱われるためです。
つまり C++ では『0b0000 & 0b0101
が 0
を返すので偽』となりますが、 Ruby では『0b0000 & 0b0101
が 0
を返しても真』となってしまうからです。
def check n if n & 0b0001 "OK" else "NG" end end p check 0b1111 # => "OK" p check 0b1100 # => "NG"
これを正しく動作させるためにはビット演算だけではなくて『結果が 0
かどうか』も判定する必要があります。
def check n if n & 0b0001 != 0 "OK" else "NG" end end p check 0b1111 # => "OK" p check 0b1100 # => "NG"
ちなみにこれを回避するために Integer#anybits?
みたいなメソッドを入れるかどうかみたいな議論がされていたりします。
まとめ
真理値以外を返す比較演算子もあるので注意しましょう。