NoMethodError: undefined method ‘○○○’ for nil:NilClassの対策

NoMethodErrorはRubyでプログラムを書いていると、最もよく目にするエラーの一つだと思う。

Rubyではメソッドの引数となる値の型を要求しない。
Javaなどの言語では、メソッド定義時に引数の型を指定し、実行時にはその型を引数として渡す必要がある。
しかし、Rubyでは

のように型指定なしでメソッドの引数を指定できる。
ここで求められているのはarrayがeachというメソッドを持っている、ということだけである。

仮にArrayオブジェクトを渡す場合問題ないが、Stringオブジェクトを渡してしまった場合、Rubyは例外を発生させる。

Rubyは引数の型が何であろうと、インターフェースさえ一致すれば何を与えても良い。
上の例だと、eachメソッドが使えるオブジェクトであればArrayでなくても良いということ。
与えられた値が何であろうと、実際にメソッド呼び出しを行ってみて(今回のケースではeachを実行してみて)、メソッドがない場合は例外を発生させるのがRubyの仕様である。
(これは悪いものではなく、上の例だと、Stringオブジェクトが入ってきたことを教えてくれている。)

しかし、ここで厄介な問題なのが、
仮にarrayが指し示すものがnilだった場合だ。
nilもオブジェクトなので
NoMethodError: undefined method ‘each’ for nil:NilClass
このようにnilクラスにeachメソッドはないと怒られてしまう。
なぜ厄介な問題かというと、プログラムの実行の中で、意図せずnilが入り込むケースは思いの他多いからだ。
Rubyを書いたことがある人なら、一度は上のエラーに遭遇したことがあるはずだ。

○対策
1 nilを前提に考える
とにかく、nilオブジェクトが入っていることを前提にプログラムを書くこと
簡単なのはnil?メソッドを使うこと。
これはレシーバがnilの場合Trueを返してくれるので、条件分岐してnilの場合、メソッドを実行しない等で対策できる。

2 to_s、to_aなどで変換する
Object#to_sやObject#to_aはかなり便利である。

例えば、メソッドの戻り値としてStringを期待するメソッドを作る場合、to_sメソッドを使えば、nilかどうかを意識することなく、常にStringを返すメソッドを作ることができる。
もちろん時と場合によるが、nilへの対策として覚えておくといい。

まとめ
・nilオブジェクトに注意する
・nil?メソッドで確認して条件分岐する
・場合によってはto_sメソッドなどが有効となる

スポンサーリンク
スポンサーリンク
スポンサーリンク

シェアする

  • このエントリーをはてなブックマークに追加

フォローする

スポンサーリンク
スポンサーリンク