すでにメンバーの場合は

無料会員登録

GitHubアカウントで登録 Pikawakaが許可なくTwitterやFacebookに投稿することはありません。

登録がまだの方はこちらから

Pikawakaにログイン

GitHubアカウントでログイン Pikawakaが許可なくTwitterやFacebookに投稿することはありません。

Ruby

【Ruby】 論理演算子(!, &&, ||, not, and, or)をまるごと学ぼう!

ぴっかちゃん
ぴっかちゃん

論理演算子とは、「真」と「偽」の2つの値だけで行う計算(論理演算)を表す記号のことです。Rubyの論理演算子には、「!, &&, ||, not, and, or」が用意されています。

論理演算子を使用すると、複数の条件式を組み合わせて判定することができます。

例えば、次のコードの||左辺と右辺どちらかの結果が真ならば、式全体の結果が真となり、then以下に記述する処理を実行することができます。

color.rb | 「||」を使用した場合
1
2
3
4
5
6
color = 'red'

if color == 'red' || color == 'blue' then
  puts  '色は赤、もしくは青です。' # 真だった場合に実行される
end
# 実行結果  色は赤、もしくは青です。

左辺のcolor == 'red'が真となり、色は赤、もしくは青です。が出力されていますね。

この記事では、各論理演算子の特徴や挙動をコードベースで学ぶことができます。論理演算子は条件分岐でよく使われるので是非マスターしましょう。

論理演算子とは?

論理演算子を理解するには、真偽値について知る必要があります。

真偽値とは簡単に説明すると、「ある条件が正しい(真)か正しくない(偽)か表すための値のこと」です。Rubyでは偽になる値はnilとfalseだけで、それ以外の値はすべて真になります。

Rubyの真偽値

例えば、ifは条件式の結果が「真」の場合にthen以下の処理を実行しますが、この条件式に10nilをそれぞれ指定した場合は、次のようになります。

ifの条件式に10を指定した場合
1
2
3
4
if 10 then
  puts "真です" # 条件式の結果は「真」なので実行される
end
# 実行結果:  真です 
ifの条件式にnilを指定した場合
1
2
3
4
5
6
if nil then
  puts "真です"
else
puts "偽です" # 条件式の結果は「偽」なのでこちらが実行される
end # 実行結果: 偽です

上記のように真偽値を使えば、条件が正しいか正しくないか表せますね。

そして真偽値は、2つ以上の真偽値を計算することができます。
加算の1+2の計算結果が3であるように、真偽値も計算によって1つの結果(答え)を得ることができます。

このように2つ以上の真偽値を計算して1つの結果を得ることを「論理演算」と呼びます。

論理演算

四則演算には加算・減算・徐算・乗算の種類がありますが、それぞれ表すのに+ - / *の記号が使われています。論理演算にも主に論理否定(NOT)、論理和(OR)、論理積(AND)の種類があり、! && ||などの記号で表せます。

このような論理演算を表す記号のことを「論理演算子」と呼びます。

論理演算子

ポイント
  1. 真偽値とは、ある条件が正しい(真)か正しくない(偽)か表すための値のこと
  2. 論理演算とは、2つ以上の真偽値を計算して1つの結果を得ること
  3. 論理演算子とは、論理演算を表す記号のこと

論理演算子の種類

Rubyの論理演算子には、次の表のように「!, &&, ||, not, and, or」が用意されています。

論理演算子 意味
!
not
!A Aが真のとき偽、偽のとき真を返す
||
or
A || B AもしくはBが真のとき真、どちらも偽のとき偽を返す
&&
and
A && B AかつBが真のとき真、それ以外は偽を返す

A || Bのように<左辺> [論理演算子] <右辺>の式は左から順番に評価されます。

式の評価の順番

そして、次の画像のように左辺(A)を評価した時点で式全体の結果が決まらない場合のみ右辺(B)を評価(短絡評価)します。

短絡評価)

また、Rubyの論理演算の結果(答え)は最後に評価された値になります。(後述します。)

以上の特徴を踏まえて各論理演算子について詳しくみていきましょう。

ポイント
  1. <左辺> [論理演算子] <右辺>の式は、左から順番に評価される
  2. 左辺を評価した時点で式全体の結果が決まらない場合のみ右辺が評価される
  3. 最後に評価された式が式全体の結果(計算の答え)になる

論理和(OR)

論理和(OR)を表す論理演算子は、||orです。

論理和の文法
1
2
 ||  # A || B
 or  # A or B

基本的には、||の方を使います。左辺(A)が偽なら右辺(B)を評価しますが、左辺が真ならその時点で左辺の値を返します。

それではサンプルコードでこの挙動を確認しましょう。

論理和の挙動を確認しよう

Rubyで偽の値はnilとfalseだけなので、次のコードで真になる値は10trueです。

1
2
nil || false || 10 || true
#(偽)|| (偽) || (真) || (真)

||左辺から順番に式を評価して「真」の時点でその値を返すので上記のコードを実行すると、次のように10を返します。

irb | サンプルコードの実行結果
1
2
irb(main):001:0> nil || false || 10 || true
=> 10

真である10が評価された時点で「式全体の結果として10が返る」ので、右辺の真であるtrueは評価されずに終わります。

全ての式の結果が偽の場合は、次のコードのように最後に評価された偽の値を返します。

irb | すべて偽の場合
1
2
irb(main):014:0> nil || false
=> false
ポイント
  1. 左辺が偽なら右辺が評価される
  2. 真が評価された場合は、その時点で値を返す
  3. 全ての式が偽の場合は、最後に評価された値を返す

論理和の使い所1 (ifとの併用)

||は、次のコードのようにifと複数の条件を組み合わせることができます。

color.rb | ifに「||」を使用した場合
1
2
3
4
5
6
7
color = 'blue'

if color == 'red' || color == 'blue' || color == 'green' then
puts '色は赤、青、緑のどれかです。' end # 実行結果 色は赤、青、緑のどれかです。

ifは条件式の結果が真の場合にthen以下の処理を実行するので、上記ではcolor == 'blue'が真でtrueを返すので処理が実行されます。

次の表のように||の成立するパターンは3つあります。

A || Bが成立するパターン 式全体の結果
A=true, B=true(両方がtrue) true
A=true, B=false(片方がtrue) true
A=false, B=true(片方がtrue) true

論理和の使い所2 (変数に代入)

||は、次のように演算結果を変数(value)に代入して使用することができます。

1
2
value = nil || false || 10 || true
       # (偽)|| (偽) || (真) || (真)

変数(value)には、次のように最初に評価された「真」の値(10)が代入されます。「真」がない場合は、最後に評価された偽の値が代入されます。

1
2
irb(main):002:0> value
=> 10

また||を上手く使うことで、未定義などで起こるエラーを防ぐことができます。

例えば、次のコードのnumberのように定義されていないローカル変数を呼び出した場合にはNameErrorが発生します。

1
2
irb(main):001:0> number
NameError (undefined local variable or method `number' for main:Object)

このようなエラーは、「変数(number)が未定義の場合にデフォルト値を設定する」ことで防ぐことができそうですね。

そこで次のように記述すると、変数が未定義の場合に0を代入することができます。

1
2
irb(main):002:0> number || (number = 0) # 優先度で括弧が必要
=> 0

||は、左辺が偽(nil,false)か未定義だと右辺が評価されるので、上記のコードでは左辺のnumberが未定義で右辺のnumber = 0が評価されてnumberに0が代入されます。

そして、上記のコードは次のように||=を使って置き換えることができます。

1
2
irb(main):002:0> number ||= 0   #number || (number = 0)と同じ
=> 0

このように||の挙動を利用すれば、変数が偽(nil, false)か未定義のときにデフォルト値を設定することができます。

「or」と「||」の違いとは?

orは、||と同じ働きをしますが優先順位が低いです。orの優先順位は、他の演算子と比べても低い位置にあるので、考慮しなければ結果に影響を与える可能性があります。

例えば||の演算結果を変数に代入した場合は、次のコードのようになります。

irb | 「||」の演算結果を変数に代入した場合
1
2
3
4
irb(main):011:0>  is_empty = false || true
=> true
irb(main):012:0> is_empty
=> true

||は最初に評価された「真」の値が代入されるので、is_emptyにはtrueが代入されます。orもこの働きは一緒なので同じようにtrueが代入されると考えますよね。しかし、実際に代入されるのは次のコードのようにfalseです。

irb | 「or」の演算結果を変数に代入した場合
1
2
3
4
irb(main):009:0> is_empty = false or true
=> true
irb(main):010:0> is_empty
=> false # is_emptyには、falseが代入されている

最初の式の結果でtrueを返しているので、 is_emptyにはtrueが代入されているようにみえますが、orよりも=の優先度が高いのでfalseが代入されます。

orの優先順位

このようにorは優先度が低く他の演算子の影響を受けてしまうので、基本的には||を使用するようにしましょう。

論理積(AND)

論理積(AND)を表す論理演算子は、&&andです。

論理積の文法
1
2
 &&  # A && B
 and  # A and B

基本的には、&&の方を使います。 左辺(A)が偽ならその時点で左辺の値(nil か false)を返します。左辺が真なら右辺(B)を評価します。

それではサンプルコードでこの挙動を確認しましょう。

論理積の挙動を確認しよう

Rubyで偽の値はnilとfalseだけなので、次のコードで真になる値は10trueです。

1
2
10 && true && false && nil
#(真) && (真) && (偽) && (偽)

&&左辺から順番に式を評価して「真」なら右辺を評価し、「偽」ならその値を返すので、上記のコードを実行すると、次のようにfalseを返します。

irb | サンプルコードの実行結果
1
2
irb(main):001:0> 10 && true && false && nil
=> false

偽であるfalseが評価された時点で「式全体の結果としてfalseが返る」ので、右辺の偽であるnilは評価されずに終わります。

全ての式の結果が真の場合は、次のコードのように最後に評価された式の値を返します。

irb | すべて真の場合
1
2
irb(main):001:0> 10 && 0 && '' && [] && {} && 100
=> 100
ポイント
  1. 左辺が真なら右辺を評価する
  2. 偽が評価された場合は、その時点で値を返す
  3. 全ての式が真でなければ、式全体の結果が真にならない

論理積の使い所とは?

&&は、次のコードのようにifと複数の条件を組み合わせることができます。

number.rb | ifに「&&」を使用した場合
1
2
3
4
5
6
7
number = 30

if number <= 100 && number >= 50 then
puts 'numberは50以上100以下です。' end # 実行結果 numberは50以上100以下です。

ifは条件式の結果が真の場合にthen以下の処理を実行するので、上記ではnumber <= 100number >= 50のどちらも真でなければ実行されません。

次の表のように&&の成立するパターンは1つだけです。

A && Bが成立するパターン 式全体の結果
A=true, B=true(両方がtrue) true

このように条件が成立するパターンが1つしかないので、パターンが3つある||よりもコードが読みやすいですね。

「and」と「&&」の違いとは?

andは、&&と同じ働きをしますが優先順位が低いです。andの優先順位は、他の演算子と比べても低い位置にあるので、orと同様に考慮しなければ結果に影響を与える可能性があります。

例えば&&の演算結果を変数に代入した場合は、次のコードのようになります。

irb | 「&&」の演算結果を変数に代入した場合
1
2
3
4
irb(main):022:0> is_empty = true && false
=> false
irb(main):023:0> is_empty
=> false

&&は最初に評価された「偽」の値が代入されるので、is_emptyにはfalseが代入されます。andもこの働きは一緒なので同じようにfalseが代入されると考えますよね。しかし、実際に代入されるのは次のコードのようにtrueです。

irb | 「and」の演算結果を変数に代入した場合
1
2
3
4
irb(main):024:0> is_empty = true and false
=> false
irb(main):025:0> is_empty
=> true # is_emptyには、trueが代入されている

上記のis_empty = true and falseでfalseを返しているのでis_emptyにfalseが代入されたようにみえますが、andよりも=の優先度が高いのでtrueが代入されます。

andの優先順位

このようにandは優先度が低く他の演算子の影響を受けてしまうので、基本的には&&を使用するようにしましょう。

論理否定(NOT)

論理否定(NOT)を表す論理演算子は、!notです。

論理否定の文法
1
2
!  # ! A
not  # not A

基本的には、!の方を使います。 式(A)が真なら式全体(! 式)は偽になり、式が偽なら式全体は真になります。

それではサンプルコードでこの挙動を確認しましょう。

論理否定の挙動を確認しよう

Rubyでは偽になる値はnilとfalseだけなので、次のコードの式(10)の結果は真です。

irb | 10の前に!を指定した場合の挙動
1
2
irb(main):001:0> ! 10 # ! 式
=> false

そして真は、trueとして扱われるので式全体(! 10)の結果は偽としてfalseが返ります。逆にfalseを式に指定した場合は、次のようにtrueが返ります。

irb | falseの前に!を指定した場合の挙動
1
2
irb(main):002:0> ! false # ! 式
=> true

式(false)の結果は偽なので、式全体(! false)の結果は真としてtrueが返ります。論理否定の挙動をまとめると、次のようになります。

irb | 論理否定の挙動まとめ
1
2
3
4
irb(main):001:0> ! true
=> false
irb(main):002:0> ! false
=> true
ポイント
  1. ! 式は、式が真なら式全体の結果が偽になるので、falseを返す
  2. 式が偽なら式全体の結果が真になるので、trueを返す

論理否定の使い所とは?

論理否定は、比較演算子(==, !=, <, >...)を使用した式を指定することができます。
次のように!のあとの式は、括弧()で囲む必要があります。

比較演算子を使用した式を指定する場合
1
2
3
!()

!(1 < 5)

比較演算子の返り値はtruefalseなので!を使用すると、次のようになります。

irb | 式(1 < 5)が真の場合
1
2
3
4
irb(main):003:0> 1 < 5
=> true
irb(main):004:0> !(1 < 5)
=> false

(1 < 5)は真でtrueを返すので、式全体( ! (1 < 5))の結果は偽でfalseを返します。

そして、次のように式(5 == 3)が偽でfalseを返す場合は、式全体( ! (5 == 3))の結果は真でtrueを返します。

irb | 式(5 == 3)が偽の場合
1
2
3
4
irb(main):006:0> 5 == 3
=> false
irb(main):007:0> !(5 == 3)
=> true

次のようにifの条件式で使用することもできます。

sample.rb | ifの条件式に指定した場合
1
2
3
4
5
6
7
number = 5

if !(number == 3) then
puts 'numberはではありません。' end # 実行結果 numberは1ではありません。

!(number == 3)の式全体の結果は真でtrueを返すので、then以下の処理が実行されていますね。

「not」と「!」の違いとは?

notは、!と同じ働きをしますが優先順位が低いです。andの優先順位は、他の演算子と比べても低い位置にあるので、and、orと同様に考慮しなければ結果に影響を与える可能性があります。

例えば左辺に!を指定し&&と組み合わせた場合の演算結果は、次のようになります。

irb | 「!」と「&&」を使用した場合
1
2
irb(main):026:0> ! true && false
=> false

&&は左辺が偽ならその値を返して真なら右辺の評価結果が返るので、上記では左辺の! trueの結果であるfalseが返ります。notもこの働きは一緒なので同じようにfalseが返ると考えますよね。

しかし、実際には次のコードのようにtrueが返ります。

irb | 「not」と「&&」を使用した場合
1
2
irb(main):027:0> not true && false
=> true # falseではなくtrueが返る

not&&よりも優先順位が低いので、true && falseが先に評価されてfalseを返し、次にnot falseが評価されてtrueを返しているのです。

notの優先順位

このようにnotは優先度が低く他の演算子の影響を受けてしまうので、基本的には!を使用するようにしましょう。

優先順位まとめ

演算子の優先順位は次のようになります。

高い ::
[]
+(単項) ! ~
**
-(単項)
* / %
+ -
<< >>
&
| ^
> >= < <=
<=> == === != =~ !~
&&
||
.. ...
?:(条件演算子)
=(+=, -= ... )
not
低い and or

演算子の中で優先順位が低いのは、not、and、orということがわかります。

参考文献:Rubyリファレンスマニュアル 演算子式

論理演算子まとめ

各論理演算子の特徴は、次の表のようにまとめられます。

演算子 意味 優先順位
|| A || B AもしくはBが真のとき真、
どちらも偽のとき偽を返す
高い
&& A && B AかつBが真のとき真、
それ以外は偽を返す
高い
! !A Aが真のとき偽、
偽のとき真を返す
論理演算子の中で1番高い
or A or B ||と同じ 演算子の中で最も低い
and A and B &&と同じ 演算子の中で最も低い
not not A !と同じ 演算子の中で最も低い

||&&は、式全体の結果として評価された値を返します。

  • A || Bは、左辺(A)を評価して真ならその値を返し、偽なら右辺(B)の値を返す
  • A && Bは、左辺(A)を評価して偽ならその値を返し、真なら右辺(B)の値を返す

よく使われる論理演算子なので覚えておきましょう。今回のようにRubyの基礎から徹底的に学びたい方は、チェリー本と呼ばれるこちらの参考書が良いでしょう。

この記事のまとめ

  • 2つ以上の真偽値を計算して1つの結果を得ることを「論理演算」と呼ぶ
  • 論理演算を表す記号のことを「論理演算子」と呼ぶ
  • 式は左辺から順番に評価されて、式全体の結果が決まらない場合のみ右辺を評価する(短絡評価)

7

わかった!