2022-09-30
ネストされた配列やハッシュを参照する際、途中で指定要素が未定義だとエラーが発生してしまう。 ```ruby a = [[1,2,3], [4,5,6], [7,8,9]] a[3][1] # ERROR ``` これを回避するには、各要素があるのかを判定する必要があるが、ネストが深いとそれも面倒である。 ```ruby a[3] && a[3][1] # => nil ``` Ruby 2.3 より途中のオブジェクトが nil であった場合は nil を返す [dig](https://docs.ruby-lang.org/ja/latest/method/Array/i/dig.html) メソッドが追加されている。 これを RGSS にも実装する。
再帰とイテレータの2つの実装を用意してみた。 ```ruby # 再帰による実装 module Digable def dig(key, *keys) obj = self[key] return obj if obj == nil return obj if keys.empty? return obj.dig(*keys) if obj.respond_to?('dig') i = (caller.find_index {|c| c.include?("`#{__callee__}'") } || -1) + 2 msg = "#{obj.class} does not have #dig method : index #{i} key #{keys[0]}" raise TypeError, msg, caller(i) end end ``` ```ruby # イテレータによる実装 module Digable def dig(*keys) obj = self keys.each_with_index do |k,i| break obj == nil if obj.respond_to?('dig') obj = obj[k] else n = caller.find_index {|c| c.include?("`#{__callee__}'") } || 2 msg = "#{obj.class} does not have #dig method : index #{i} key#{k}" raise TypeError, msg, caller[n+1] end end return obj end end ``` 上記のどちらかを定義して下記のコードで Array と Hash で dig を使えるようにする。 ```ruby class Array include Digable end class Hash include Digable end ``` これで、先ほどのコードが dig を使用して次のように書ける。 ```ruby a = [[1,2,3], [4,5,6], [7,8,9]] a[3] && a[3][1] # => nil # ↑これが↓こう a.dig(3, 1) # => nil ```
例のような二次元配列では大した手間ではないが、さらに配列やハッシュが入れ子になるコードでは格段に楽になる。
コメント






 ※ コメント内にURLを含めるには、バッククォート(`)をURLの直前に付け加えてください。



トラックバック
トラックバックURL:
http://cacaosoft.blog42.fc2.com/tb.php/819-ac2f912f
≪ トップページ ≫
カテゴリー
最近の記事
最近のコメント
タグクラウド

リンク