undefined method for nil の原因と直し方
nilが入った変数に対してメソッドを呼び出そうとしたときに出るエラーです。値を取得し損ねた変数(見つからなかった検索結果など)をそのまま使うと、必ずここで止まります。
エラーメッセージの読み方
main.rb:3:in `<main>': undefined method `upcase' for nil (NoMethodError)
main.rb- ファイル名
3- 行番号 — 実際にクラッシュした行
<main>- 発生場所 — <main> ならトップレベル、メソッド名ならそのメソッドの中
NoMethodError- 例外クラス — 何が起きたか。ここを検索するのが最短です
undefined method `upcase' for nil- 詳細メッセージ — どの値が問題だったか
このエラーが出る典型パターン
パターン1
1 users = ["taro", "hanako"] 2 found = users.find { |u| u == "jiro " } ^ 3 puts found.upcase
main.rb:3:in `<main>': undefined method `upcase' for nil (NoMethodError)
findは条件に一致する要素が無いとnilを返します。見つからなかった変数にメソッドを呼ぶとここで止まります。
直し方: jiro を hanako にします。
広告
広告スロット(未設定)
パターン2
1 scores = {math: "eighty", science: "ninety"} 2 english = scores[:english] ^ 3 puts english.upcase
main.rb:3:in `<main>': undefined method `upcase' for nil (NoMethodError)
ハッシュに存在しないキーでアクセスすると、エラーにならず静かにnilが返ります。
直し方: :english を :math にします。
パターン3
1 nums = [15.5, 42.2, 7.1] 2 big = nums.detect { |n| n > 100 } ^ 3 puts big.round
main.rb:3:in `<main>': undefined method `round' for nil (NoMethodError)
条件に合う要素が無いとdetectはnilを返します。しきい値が高すぎて何も見つからないと、後の行でエラーになります。
直し方: 100 を 10 にします。
パターン4
1 config = {timeout: 30} 2 retries = config[:retries] ^ 3 puts retries + 1
main.rb:3:in `<main>': undefined method `+' for nil (NoMethodError)
ハッシュに登録されていないキーの値はnilです。nilに対する+も未定義のメソッド呼び出しになります。
直し方: :retries を :timeout にします。
パターン5
1 inventory = {"apple" => 5, "banana" => 3} 2 count = inventory["orange"] ^ 3 puts count + 1
main.rb:3:in `<main>': undefined method `+' for nil (NoMethodError)
在庫に無い商品名で検索すればnilが返ります。存在確認をせずに計算に使うとエラーになります。
直し方: orange を apple にします。
よくある誤解
「変数に何か入っていればメソッドを呼べるはず」という思い込みは誤りです。nilは専用のクラスNilClassのオブジェクトで、upcaseのような文字列用メソッドは持っていません。
まとめ
undefined method for nilは初級でつまずきやすい項目です。上の5パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。