2項演算子を使った3項演算子風実装

exp and val1 or val2

expがtrueならval1、falseならval2を返す。


trueとfalseを返すような使い方をすると難しいけど、(val1がfalseだとval2が選択されてしまう)そういう使い方しなければ便利。

  • expがtrue

val1(nil,false以外)が選択され、orは左の項がfalseかnilでなければ左の項を選択するので結果としてval1を得る

true and val1 or val2
↓
val1 or val2
↓
val1
  • expがfalse(nil)

and演算子はfalse/nilの時は左の項つまりfalse/nilが選択されるがorで強制的に右の項が選択されるので結果としてval2を得ることができる。

false/nil and val1 or val2
↓
false/nil or val2
↓
val2


値を返さない関数(print)などはnilとみなされるのでandやorを使うと関数を連結できたりと変態的に使うこともできるけど、あんまりやりすぎると読めなくなるので注意。

function test(a,b)
t=a==b and print(string.format("a(%d) == b(%d) -> true",a,b)) or print("ok") and print("a==bのとき処理されない") or print("a==bのとき処理される")
end
test(1,1)
print("")
test(2,1)

------------------------
a(1) == b(1) -> true
ok
a==bのとき処理される

ok
a==bのとき処理されない


exp := a binop b なので代入や関数の引数やif文の評価を伴わなければならないので、何もしない関数や何にも使われてない変数に代入するなりしないとエラーが出てしまうのがうざったいけど単独で使うことはほとんどないと思うので大して問題にはならない。
golfの時は結構問題になるけど。

a and b    -- <-error
t=a and b  -- <-ok