if文の中で == のつもりで = を書くと常に真になる
if文の条件に == の代わりに = を書くと、それは比較ではなく代入として実行されます。代入式の評価結果は代入した値そのものなので、0以外の値であれば条件は常に真になります。
なぜエラーが出ないのか
出力: count is five
(エラーなし)- Rubyは何も報告しません。文法として正しいためです
出力: count is five- 実際の挙動 — 期待した結果と食い違っている箇所
見つけ方- エラーが出ないので、出力を目で確かめるしかありません。この種の誤りが最も発見が遅れます
このエラーが出る典型パターン
パターン1
1 count = 0 2 if count = 5 ^ 3 puts "count is five" 4 else 5 puts "count is not five" 6 end
出力: count is five
if count = 5は比較ではなく代入です。代入式の値は5(真扱い)になるため、条件は常に真になります。
直し方: = を == にします。
広告
広告スロット(未設定)
パターン2
1 status = "pending" 2 if status = "done" ^ 3 puts "task is done" 4 else 5 puts "task is not done" 6 end
出力: task is done
=を書くとstatusの中身が"done"に上書きされたうえ、条件は常に真になってしまいます。
直し方: = を == にします。
パターン3
1 flag = false 2 if flag = true ^ 3 puts "flag is on" 4 else 5 puts "flag is off" 6 end
出力: flag is on
falseで初期化したはずのflagが、代入によって常にtrueへ書き換えられてしまいます。
直し方: = を == にします。
パターン4
1 level = 1 2 if level = 99 ^ 3 puts "max level" 4 else 5 puts "not max level" 6 end
出力: max level
比較のつもりで書いた=は代入として実行され、右辺の値がそのままlevelに入ります。
直し方: = を == にします。
パターン5
1 ready = false 2 if ready = 1 ^ 3 puts "ready" 4 else 5 puts "not ready" 6 end
出力: ready
0や1のような値は=による代入結果としても真になるため、意図しない分岐に入り込みます。
直し方: = を == にします。
よくある誤解
「=はifの中では自動的に比較として扱われるはず」という思い込みは誤りです。Rubyは=をそのまま代入として実行し、警告を出すことはあっても実行は止めません。比較したい場合は必ず==を使う必要があります。
まとめ
if文の中で == のつもりで = を書くと常に真になるは初級でつまずきやすい項目です。上の5パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。