Rubyのdigメソッドの便利な使い方

こんにちは!kossyです!




さて、今回はRubyのdigメソッドの便利な使い方について、
ブログに残してみたいと思います。





環境
Ruby 2.6.3
MacOS Catalina



まずはドキュメント

はい、まずはドキュメントを読んでみましょう。

Hashクラスに生えているdigメソッドのドキュメント

dig(key, ...) -> object | nil[permalink][rdoc][edit]
self 以下のネストしたオブジェクトを dig メソッドで再帰的に参照して返します。途中のオブジェクトが nil であった場合は nil を返します。

[PARAM] key:
キーを任意個指定します。
h = { foo: {bar: {baz: 1}}}

h.dig(:foo, :bar, :baz) # => 1
h.dig(:foo, :zot, :xyz) # => nil

g = { foo: [10, 11, 12] }
g.dig(:foo, 1) # => 11

出典: https://docs.ruby-lang.org/ja/latest/method/Hash/i/dig.html


Arrayクラスに生えているdigメソッドのドキュメント

dig(idx, ...) -> object | nil[permalink][rdoc][edit]
self 以下のネストしたオブジェクトを dig メソッドで再帰的に参照して返します。途中のオブジェクトが nil であった場合は nil を返します。

[PARAM] idx:
インデックスを整数で任意個指定します。
a = 1, [2, 3]

a.dig(0, 1, 1) # => 3
a.dig(1, 2, 3) # => nil
a.dig(0, 0, 0) # => TypeError: Integer does not have #dig method
[42, {foo: :bar}].dig(1, :foo) # => :bar

出典: https://docs.ruby-lang.org/ja/latest/method/Array/i/dig.html

このメソッドのキモは、「途中のオブジェクトが nil であった場合は nil を返します」ですね。


ユースケース

「渡ってくるハッシュのkeyがnilかもしれない」という場合は、digメソッドが使えるかと思います。

通常、以下のような使い方をしようとすると、NoMethodErrorエラーが発生してしまいます。

irb(main):001:0> params = {}
=> {}
irb(main):002:0> params[:articles]
=> nil
irb(main):003:0> params[:articles][:title] = "title"

NoMethodError (undefined method `[]=' for nil:NilClass)

そこで、digメソッドの出番です。

以下のようなハッシュがあった場合、

json = {
  user: {
    name: 'kossy',
    addresses: {
      city: '東京都'
     }
  }
}

other_json = { 
  user: { 
    name: 'kossy'
  }
}

other_jsonの方はaddressesキーがありませんが、
digメソッドを使えばaddressesキーを呼び出してもエラーにはなりません。

json.dig(:user, :addresses, :city)
=> "東京都"

other_json.dig(:user, :addresses, :city)
=> nil

このように、「渡ってくるハッシュのkeyがnilかもしれない」という場合は、
digメソッドが使えるかと思います。




勉強になりました。




参考にさせていただいたサイト