みなさんはこんな経験ありますか?
コードは超簡単なのに、思った通り動かない。
ありますよね?ね?
あるある…!そんな気持ちでご覧になってください。
まずは問題となったコードがこちら
hoge = “ZZZ”
huga = hoge == “AAA” || “BBB” ? true : false
p huga
ええ、簡単です。
超簡単なんですが、そんな簡単なコードで小一時間はまってしまったので
自分への戒めとして、今回の記事を書こうと思います。
やりたかったこと
やりたいことはとっても簡単。
三項演算子を使って hogeに”AAA”、もしくは”BBB”が入っていたらtrue、それ以外はfalse
をhugaに代入する。
という処理。
今回、hogeに”ZZZ”が代入されているので
想定している動作としては、hugaに false が代入されてそのまま出力される。というものでした。
答え合わせ
しかし実際に出力される値は true!
なぜだ…なぜなんだ…絶対に正しいコードを書いているはず…!なぜだぁー!
なんてことを考えていたら一時間がたっていました。
思い込みというのは怖いですね…この時の自分をひっぱたいてやりたい…
なぜか?
true が返ってくる理由は2つ!
1.演算子の優先順位
rubyの演算子の優先順位は以下の通り
高い :: [] +(単項) ! ~ ** -(単項) * / % + - << >> & | ^ > >= < <= <=> == === != =~ !~ && || .. ... ?:(条件演算子) =(+=, -= ... ) not 低い and or
見ての通り、|| は == より優先順位が低いんですね。
ということは今回のコードは、まず最初にこう判定されます
hoge == “AAA” => #false
なるほど…言われればそりゃそうだ。
これに気づいた時点でもう理由ははっきりしましたが、ついでにもう一つ説明しておきます。
2.rubyの真偽判定
rubyは nilとfalse 以外は真と判定する。
ということはこちら
"BBB" => # true
rubyをやっている人にとっては当たり前のことですね。
rubyからどう見えているか
以上の理由から今回のコードがrubyでどう判定されているか。
わかりやすくすると、このようになります
hoge = “ZZZ”
huga = (hoge == “AAA”) || (true) ? true : false
p huga
どう見ても true しか出力されません!
実現するには
hoge = “ZZZ”
huga = hoge == (“AAA” || “BBB”) ? true : false
p huga
これだけ!括弧つけるだけ!(なんかイケてない気がするけど…)
なぜこんなことでハマったのか
私はこのとき自分の書き方が間違っているなんてことは微塵も考えていませんでした。
煮詰まりすぎて「既存バグか…?」なんて考え始めちゃったりしていました。
今考えれば本当にバカですねー…
ハマった理由はズバリ『思い込み』です。
自分は絶対に正しいことを書いている。という思い込みですね。
自分の作業に絶対なんてことは絶対ないんです!
思い上がるな自分!!
まとめ
思った通りに動かない!意味わかんないエラーが出た!
そんなときはまず自分を疑いましょう。
- 書き方あってる?
- 仕様把握できてる?
- 疲れてない?
基本中の基本ですが、超大事なことですね。思い知らされました。
みなさんもコーディングの際は、思い込みをしないよう冷静に対処してくださいね!