未定義の変数・メソッド・定数を参照したときのエラーです。スペルミス、定義順、require漏れ、スコープ切れが主な原因。uninitialized constantやNoMethodErrorとの違いも下で整理します。
message = "Hello"
puts mesage
message = "Hello"
puts message
▶ 修正済みコードを実行エディタで開く
エラーに出た名前と定義した名前が一致しているか確認します。Rubyは大文字小文字を区別します。文字列を書くつもりならクォート""で囲みます(囲まないとメソッド名と解釈されます)。
| メッセージ | 主な原因 | 確認すること |
|---|---|---|
undefined local variable or method `x' | 綴り違い/定義前に参照/クォート忘れ | 名前の一致・代入行の位置・""の有無 |
uninitialized constant Foo | require漏れ/名前空間違い/綴り | 定義ファイルの読み込み・Bar::Fooか・大文字小文字 |
uninitialized constant Foo::Bar | Fooの中にBarが無い | 正しい階層・別モジュール所属でないか |
undefined method `x' for ... | これはNoMethodError(別ページ) | レシーバの型・nilでないか |
... Did you mean? y | 打ち間違い(候補yが正解のことが多い) | 提案どおりに直す |
NoMethodErrorはNameErrorのサブクラスです。切り分けはエラー文の形で判断します。
| NameError | NoMethodError | |
|---|---|---|
| 書き方 | 名前だけ参照 foo | レシーバ付き obj.foo |
| エラー文 | undefined local variable or method | undefined method `foo' for ... |
| 典型原因 | 綴り違い・定義前参照・定数未読込 | レシーバがnil・型違い・メソッド名違い |
user = User.new("Sato")
# → uninitialized constant User
class Userを読み込んでいない。require_relative "user"(gem なら require "gem名")を先頭に。Admin::User なのに User と書いている。フルパスで書くか include Admin。APIClient と ApiClient、HTTP と Http の混同。定義側の表記に合わせる。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)
▶ この例を実行エディタで開く
ブロック(each do |x| ... end や { })は外のローカル変数を参照できます。スコープが切れるのはdef・class・moduleです。
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?(名前)で存在を確認できます。