配列の範囲外アクセスはエラーにならず nil を返す
存在しない添字で配列にアクセスしても、Rubyはエラーを出さずnilを返すだけです。その後nilに対してメソッドを呼び出すと、そこで初めてNoMethodErrorになります。
なぜエラーが出ないのか
出力: nil
(エラーなし)- Rubyは何も報告しません。文法として正しいためです
出力: nil- 実際の挙動 — 期待した結果と食い違っている箇所
見つけ方- エラーが出ないので、出力を目で確かめるしかありません。この種の誤りが最も発見が遅れます
このエラーが出る典型パターン
パターン1
1 nums = [1, 2, 3] 2 puts nums[10].inspect ^
出力: nil
存在しない添字にアクセスしても例外にはならず、Rubyは黙ってnilを返します。
直し方: 10 を 1 にします。
広告
広告スロット(未設定)
パターン2
1 fruits = ["apple", "banana"] 2 puts fruits[5].inspect ^
出力: nil
配列の要素数を超えた添字を指定しても、エラーにならず結果はnilになります。
直し方: 5 を 1 にします。
パターン3
1 scores = [70, 80, 90] 2 puts scores[100].inspect ^
出力: nil
範囲外アクセスで即座に例外が飛ぶ言語の感覚のままだと、このnilの静かな発生に気づけません。
直し方: 100 を 2 にします。
パターン4
1 names = ["A", "B", "C"] 2 puts names[9].inspect ^
出力: nil
添字が範囲内かどうかは、配列の要素数(length)と照らし合わせて確認する必要があります。
直し方: 9 を 0 にします。
パターン5
1 data = [1, 2] 2 puts data[7 ].inspect ^
出力: nil
このnilが後続の計算に紛れ込むと、ずっと後の行で初めてNoMethodErrorとして表面化します。
直し方: 7 を 0 にします。
よくある誤解
「範囲外にアクセスすればすぐ例外で止まるはず」という他言語の感覚は通用しません。Rubyの配列アクセスは範囲外でも黙ってnilを返すため、エラーが起きるのはずっと後の行になることがあります。
まとめ
配列の範囲外アクセスはエラーにならず nil を返すは初級でつまずきやすい項目です。上の5パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。