落書きノート

ふと自分が気になった事を書いてます

Ruby資格問題集 今回の成果

今回は論理演算子について勉強になりました。

if true && true; 1; end #=> 1
if nil && 10; 1; end #=> nil
if false || true; 1; end #=> 1
if nil || false; 1; end #=> nil
if !true; 1; end #=> nil

if文で論理演算子を使うのは簡単なのですが、問題は以下のコードです。

a = nil && 1 #=> nil
a = 1 || 2 #=> 1

論理演算子において左辺で式の結果が確定する場合は、右辺を評価しないそうです。式の評価値は最後に評価したオペランドとなります。上記のコードでは、左辺で結果が確定するので、論理演算子の左辺の値が返るそうです。もう少しわかり易く説明が無いものかと思っていたら、Rubyの公式サイトに説明が書かれていました。

左辺を評価し、結果が偽であった場合はその値(つまり nil か false) を返します。左辺の評価結果が真であった場合には 右辺を評価しその結果を返します。

「最後に評価したオペランドの値を返す」という特徴を利用して、変数のデフォルト値を下記のプログラムのように簡単に書くことも出来ます。

b = b || 1 #bが初期化していない(nil)場合に1を格納
c ||= 1 #cが初期化していない(nil)場合に1を格納

b || 1を評価する時点では、まだbに対する代入は行われていませんが、コードの記述順がbへの代入が先なのでエラーにならず、bへの参照は初期化していない状態を表すnilになります。

自己代入演算子「||=」は、よく使用するのでイディオムとして覚えておきましょう…とのことです。

andの優先度に関するコードは下記のようになります。

p 1 && 2 # p (1 && 2)と同義。2が出力される。
p 1 and 2 # p (1) and 2と同義。1が出力される。

最初の式では論理積の結果がpに渡されているのに対し、後者ではpの実行結果と2の論理積が渡されています。andの魅力が少なくて、pに1が奪われています。&&を使った式と同じ結果にするには、論理演算の式をかっこで囲む必要があります。

p (1 and 2) # 2が出力される

Rubyに限らず、プログラミングの基礎知識がしっかりしていないと難しいと今回のことでわかりました。また読み進めておきます。