Rubyでは真偽とtrue/falseは別物だよ! というお話

今日は、Rubyの true, false と、真偽は別物だよというお話をします

これは何?

会社blogで公開しようとした直前に、上位互換の記事が出てお蔵入りしてしまった可愛そうなblog記事です

techracho.bpsinc.jp

供養と自分の学習記録も兼ねて、個人ブログにupいたします

🙏🙏🙏🙏🙏🙏🙏🙏🙏🙏🙏🙏🙏🙏🙏🙏🙏🙏🙏🙏

真偽とは

Rubyにおいては、 真偽は以下のように定義されてます

  • 偽 : false または nil
  • 真 : 偽値でないすべて

Ruby では false または nil だけが偽で、それ以外は 0 や空文字列も含め全て真です。

制御構造 (Ruby 2.6.0)

true, false とは

真偽を代表するオブジェクトであって、これ以外の値も、上記で説明したように真偽を取ります

  • なお、true, false とも、あるclassのシングルトンのインスタンスです

true は TrueClass クラスの唯一のインスタンスです。 true は真を表す代表のオブジェクトです

class TrueClass (Ruby 2.6.0)

false は FalseClass クラスの唯一のインスタンスです。 false は nil オブジェクトとともに偽を表し、 その他の全てのオブジェクトは真です。

class FalseClass (Ruby 2.6.0)

末尾が ? のメソッドは true, false を返すべきなの? 真偽を返せばよいの?

さて、ここまで true, false と真偽値の違いを説明したのは、上記の疑問のためです

具体的には if hoge? == false という実装をコードレビュー中に見かけて、これが正しいのか正しくないのか論理的に説明が出来なかったために調べ始めました

先に自分なりの結論

末尾が ? のメソッドは true, false を返すべき
ただし、それ利用する側は、true, false 以外の真偽が帰ってくる可能性を考慮して実装すべき

その理由

Rubyのドキュメントでは、? が末尾につくメソッドは慣用的に 真偽値 を返せと言われているためです

ドキュメントを探す限り真偽値の定義は見つかりませんでしたが、おそらくは true/falseのことでしょう

  • 真偽だと全てのオブジェクトを指すことになるため、わざわざ明記する理由もないと思うので

慣用的に、真偽値を返すタイプのメソッドを示すために使われます。

Rubyで使われる記号の意味(正規表現の複雑な記号は除く) (Ruby 2.6.0)

ただし、「慣用」なので使う側は、安全側に倒したほうがよいと考えています

  • 実装者によっては偽のつもりで nil を返したり、真のつもりで true 以外の値を返すことも十分にありえるので

まとめ

  • true / false と真偽は別物
  • 偽は、falsenil。真はそれ以外のオブジェクトすべて
  • 末尾に ? がつくメソッドは真偽ではなく true / false を返すべきだけれど、それを期待しすぎないほうが安全

以上になります

おまけ

Rubyの真偽の設計思想については、以下の記事が読み応えがありオススメです

qiita.com