#はじめに
下記の各式の違いがわからず、調べた際に時間がかかったため、調べたことをまとめておきます。
「普段「&&」や「&」を雰囲気で使っているが、実際どう違うの?」という方の参考になれば幸いです。
(p false) && (p true)
(p false) and (p true)
(p false) & (p true)
###この記事を書いている人
- 実務経験1年未満のエンジニア
###対象読者
- 上記各式の実行結果に確信がない方(一番最後に実行結果書いています)
- 「&&、&、and」や「|| 、| 、or」がどう違うか改めて確認したい方
###環境
- Ruby 2.7.2
#分類早見表
(これを見てわかる方はここまでで大丈夫です。下記の分類についての説明をこれ以降します。)
記号 | 分類① | 分類② |
---|---|---|
&&、and | 制御構造 | 論理演算子(これらの違いは演算子の優先順位) |
‖、or | 制御構造 | 論理演算子(これらの違いは演算子の優先順位) |
& | メソッド | Integer#&、Array#&、True(False,Nil)Class#& |
❘ | メソッド | Integer#&、Array#&、True(False,Nil)Class#& |
*演算子の優先順位
参考: Ruby リファレンスマニュアル
*レシーバー
メソッドの呼び出し元のオブジェクト
#分類①について
###演算子は制御構造とメソッドの2種類に分類される
制御構造
= ?: .. ... not && and || or ::
メソッド
| ^ & <=> == === =~ > >= < <= << >>
+ - * / % ** ~ +@ -@ [] []= ` ! != !~
*制御構造
コンピュータプログラムで、命令が実行される流れを定めたもの
参考: Rubyリファレンスマニュアル(制御構造)
#分類②について
##論理演算子
- 複数の式に対して、式全体の真偽を判定するもの(この判定の仕方が論理演算子毎に異なる)
- 式の評価は短絡評価(式全体の真偽が決定した時点で終わる)であり、最後に評価した式の戻り値が式全体の戻り値となる
参考: 短絡評価(Wikipedia)
###&&(論理積)
式の全てが、真の場合に真
###||(論理和)
式の少なくとも1つが、真の場合に真
参考: 論理演算子
Integer#&、Array#&、True(False,Nil)Class#&
「&」や「|」はメソッドのため、レシーバー(呼び出し元のオブジェクト)によって挙動が変わる点に注意
(* 「Integer#&」、「Array#&」はここでは直接関係ない内容のため説明を省略します。)
True(False,Nil)Class#&
「true、false、nil」に対して呼び出す場合は、True(False,Nil)Classクラスのインスタンスメソッド
ポイントしては、両辺(厳密にはレシーバーと引数の両方)の式が評価される
(各メソッドの挙動については下記参照)
#「TrueClass#&」は引数が偽であれば、falseを返す
(p true) & (p "hoge")
true
"hoge"
=> true
(p true) & (p false)
true
false
=> false
#「FalseClass#&、NilClass#&」は引数に関わらず、falseを返す
(p false) & (p true)
false
true
=> false
(p false) & (p false)
false
false
=> false
参考: Rubyリファレンスマニュアル(True#&)
参考: Rubyリファレンスマニュアル(False#&)
参考: Rubyリファレンスマニュアル(Nil#&)
#まとめ
上記を踏まえ、両辺(の式の戻り値)の真・偽によって実際の評価の流れがどうなるか
式 | 実行結果 |
---|---|
左辺 && 右辺 | 左辺が偽ならそこで評価終了 (「and」も同様) |
左辺 & 右辺 | 左辺が偽でも右辺を評価 |
左辺 ‖ 右辺 | 左辺が真ならそこで評価終了 (「or」も同様) |
左辺 ❘ 右辺 | 左辺が真でも右辺を評価 |
#備考:実行結果(irb)
(p false) && (p true)
false
=> false
(p false) and (p true)
false
=> false
(p false) & (p true)
false
true
=> false