Code Fix

初級

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パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。

演習をはじめる

関連するエラー

広告
広告スロット(未設定)