ホーム › エラー解決 › Ruby › NameError
Ruby ERROR

Ruby NameError: undefined local variable の解決法

未定義の変数・メソッド・定数を参照したときのエラーです。スペルミス、定義順、require漏れ、スコープ切れが主な原因。uninitialized constantやNoMethodErrorとの違いも下で整理します。

このエラーメッセージ

NameError: undefined local variable or method `mesage'

原因

❌ エラーになるコード

NG
message = "Hello"
puts mesage

✅ 修正したコード

OK
message = "Hello"
puts message
▶ 修正済みコードを実行エディタで開く
progoのRuby実行環境(インストール不要・登録不要)でその場で動作を確認できます。

解決のポイント

エラーに出た名前と定義した名前が一致しているか確認します。Rubyは大文字小文字を区別します。文字列を書くつもりならクォート""で囲みます(囲まないとメソッド名と解釈されます)。

メッセージ別・原因早見表

メッセージ主な原因確認すること
undefined local variable or method `x'綴り違い/定義前に参照/クォート忘れ名前の一致・代入行の位置・""の有無
uninitialized constant Foorequire漏れ/名前空間違い/綴り定義ファイルの読み込み・Bar::Fooか・大文字小文字
uninitialized constant Foo::BarFooの中にBarが無い正しい階層・別モジュール所属でないか
undefined method `x' for ...これはNoMethodError(別ページ)レシーバの型・nilでないか
... Did you mean? y打ち間違い(候補yが正解のことが多い)提案どおりに直す

NameError と NoMethodError の違い

NoMethodErrorはNameErrorのサブクラスです。切り分けはエラー文の形で判断します。

NameErrorNoMethodError
書き方名前だけ参照 fooレシーバ付き obj.foo
エラー文undefined local variable or methodundefined method `foo' for ...
典型原因綴り違い・定義前参照・定数未読込レシーバがnil・型違い・メソッド名違い

uninitialized constant の3大原因

NG
user = User.new("Sato")
# → uninitialized constant User

❌ メソッドの中から外の変数を見るケース

NG
count = 10
def show
  puts count      # def はスコープが切れる
end
show
# → undefined local variable or method `count'
OK
count = 10
def show(count)
  puts count
end
show(count)
▶ この例を実行エディタで開く
progoのRuby実行環境(インストール不要・登録不要)でその場で動作を確認できます。

ブロック(each do |x| ... end や { })は外のローカル変数を参照できます。スコープが切れるのはdef・class・moduleです。

did you mean? の読み方

Ruby 2.3以降はdid_you_meanが候補を出します。ほとんどの場合その候補が正解です。

test.rb:2:in `<main>': undefined local variable or method `lenght' (NameError)
Did you mean?  length

候補が出ないときは、その名前がまだ定義されていないか、定義行より前で呼んでいる可能性が高いです。ruby -cやdefined?(名前)で存在を確認できます。

よくある質問

変数とメソッドどちらのエラー?
Rubyでは引数なしのローカル変数参照とメソッド呼び出しが同じ書き方のため、両方の可能性を示すメッセージになります。まず綴りと定義順を確認します。
NameError と NoMethodError の違いは?
NoMethodError は NameError のサブクラスです。obj.method の形で型にメソッドが無ければ NoMethodError、名前だけ参照して該当が無ければ NameError です。
uninitialized constant が出ます
定数・クラス名が見つかりません。require 忘れ/名前空間違い/綴り違いの3つを確認します。
メソッドの中で外の変数が NameError になります
def で作るメソッドは外のローカル変数を見られません。引数で渡すか定数・インスタンス変数にします。ブロックは外の変数を見られます。
did you mean? と一緒に出る名前は?
did_you_mean が候補を提案しています。多くはその候補が正解(打ち間違い)です。
文字列のつもりが NameError になります
クォートを付け忘れています。puts hello は変数/メソッド参照、puts "hello" が文字列です。
定義したのに undefined と言われます
定義より前の行で使っています。呼び出しを def/class より後ろへ移動します。
NameError を rescue で捕まえられますか?
rescue NameError で捕捉できます(NoMethodError も含む)。ただし多くはバグなので握りつぶさず直すのが基本です。