0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[Ruby] undefined method for nil:NilClass を回避するためのテクニック

Last updated at Posted at 2024-11-14

概要

nil に対してメソッドを実行しようとすると、undefined method for nil:NilClassが発生します。

nil[:hoge]
# <anonymous>': eval:1:in `<main>': undefined method `[]' for nil:NilClass (NoMethodError)

本記事では初学者の方向けに undefined method for nil:NilClass を回避するためのテクニックについてまとめました。

Tips.

nil?

最も基本的な方法です。
nil?メソッドを使ってnilであるかを事前にチェックします。

if obj.nil?
  # objがnilの場合の処理
  {}
else
  # objがnilでない場合の処理
  obj[:hoge]
end

nilであるかどうかを確認することで、エラーの発生を防ぐことができます。

nil.to_h

nilに対してto_hメソッドを呼び出すと、空のハッシュ {} を返します。
ハッシュとして扱いたいがnilである可能性があるオブジェクトに対して、安全にメソッドを呼び出すことができます。

obj = nil
hash = obj.to_h
hash[:hoge] # => nil(エラーにならない)

nil.to_a

同様に、nil.to_aは空の配列 [] を返します。
配列として扱いたいがnilである可能性があるオブジェクトに対して、安全にメソッドを呼び出すことができます。

obj = nil
array = obj.to_a
array.each do |item|
  # 処理
end

Hash(nil)

Hashメソッドにnilを渡すと、空のハッシュ{}を返します。

obj = nil
hash = Hash(obj)
hash[:hoge] # => nil(エラーにならない)

Array(nil)

Arrayメソッドにnilを渡すと、空の配列[]を返します。

obj = nil
array = Array(obj)
array.each do |item|
  # 処理
end

dig

ハッシュから値を取得する際に、digメソッドを利用できます。
※ デフォルト値を使用したい場合はfetchを利用

params = nil
value = params.to_h.dig(:hoge) # => nil(エラーにならない)

キーが存在しない場合やparamsnilの場合でも、例外が発生しません。

presence (ActiveSupport)

presenceメソッドは、オブジェクトが存在する場合はそのオブジェクトを、nilや空の場合はnilを返します。

value = obj.presence || 'デフォルト値'

これにより、オブジェクトが存在しない場合にデフォルト値を設定できます。

カスタムメソッドの定義

NilClassに対してメソッドを定義することで、nilオブジェクトでも特定のメソッドを呼び出せるようにする方法です。

class NilClass
  def [](key)
    nil
  end
end

nil[:hoge] # => nil(エラーにならない)

この方法は全体の挙動に影響を与える可能性があるため、注意が必要です。

まとめ

何かと例外が発生することがあるので、こういった小技を頭の片隅に入れておくと良いと思います。
良いRubyライフを!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?