真/偽
TrueClassのインスタンスがtrue、
FalseClassのインスタンスがfalse。
NilClassのインスタンスがnil。
1 2 |
true.class # TrueClass false.class # FalseClass |
falseとnilのみ偽として評価される。
falseとnil以外は全て真として評価。
この動きにより、変数に値が入っているかどうかは、
nilと比較する必要はなく変数を評価するだけで良い。
PHPのように変数に値が入っていることをチェックする必要はない。
if文
オーソドックスなif文。
1 2 3 4 |
compare = true if compare then "OK" end |
if文は式なのでif文を評価すると値が返る。
評価値はif式内で最後に評価された値となる。
1 2 3 4 |
a = if true 1 end p a # 1 |
後置ifという構文。簡単にコードが短くなって便利そう。だが…、
後置ifがfalseの場合でも、変数自体は確保される。が値が入らない。
意図せず変数がnilになるコードを書く可能性がある。
未定義の変数と、確保済みだが値なしの変数は明確に異なる。
1 2 3 4 |
a = 1 if true p a # 1 b = 1 if false p b # nil |
もし偽だったら、を書きたい場合はunless構文を使う。
1 2 3 |
unless false p 1 # 1 end |
単項演算子?は使える。
1 |
n = (a==10) ? true : false |
論理演算子
論理演算子は最後に評価したオペランドの値を返す。
評価結果(true,false)を返さない。
1 2 |
x = nil && 4 # nil y = 1 || 2 # 1 |
自己代入
変数が真でない場合に限りその変数に値を代入する自己代入。
これは、論理演算の際どい評価順序を利用していて、何故そうなるかは深い深い海の底にある。
1 2 |
z = z || 1 # 1 z ||= 1 # 1 |
zが真でない場合、つまりzがfalseかnilの場合に、
論理和演算子の右側のオペランドである1の評価結果(=1)がzに代入される。
未確保・未定義の変数の評価結果はnilなので、
未定義・未確保の場合に限り初期値を入れることができる。
1 2 |
z = 10 z = z || 1 # 10 |
&&とand、||とor、!とnot
&&とand、||とor、!とnotという風に、同じ意味の論理演算子が対で用意されている。
それぞれ評価時の優先順位が異なる。(以下のようになる)
1 2 |
p x && z # = p (x && z) p x and z # = (p x) and z |