Ruby 2.3引入了一种新的方法Array
并被Hash
调用dig
.我在关于新版本的博客文章中看到的例子是人为的,令人费解的:
# Hash#dig user = { user: { address: { street1: '123 Main street' } } } user.dig(:user, :address, :street1) # => '123 Main street' # Array#dig results = [[[1, 2, 3]]] results.dig(0, 0, 0) # => 1
我没有使用三嵌套平面数组.什么是如何有用的现实例子?
UPDATE
事实证明,这些方法解决了一个最常见的Ruby问题.下面的问题有20个重复,所有这些都通过使用dig
以下方法解决:
如何避免NoMethodError在嵌套哈希中缺少元素,而不重复nil检查?
Ruby Style:如何检查嵌套的哈希元素是否存在
在我们的例子中,NoMethodError
由于nil
引用而导致的是迄今为止我们在生产环境中看到的最常见的错误.
new Hash#dig
允许您nil
在访问嵌套元素时省略检查.由于哈希最适合用于数据结构未知或易变的情况,因此对此有官方支持非常有意义.
让我们举个例子吧.下列:
user.dig(:user, :address, :street1)
是不是等同于:
user[:user][:address][:street1]
在user[:user]
或者user[:user][:address]
是的情况下nil
,这将导致运行时错误.
相反,它等同于以下,这是当前的习语:
user[:user] && user[:user][:address] && user[:user][:address][:street1]
注意如何传递在其他地方创建的符号列表是微不足道的Hash#dig
,而从这样的列表重新创建后一个构造并不是非常简单.Hash#dig
允许您轻松进行动态访问,而无需担心nil
引用.
显然Hash#dig
也短得多.
需要注意的一点是,如果任何一个键变成了Hash#dig
本身就会返回nil
,这可能导致同一类错误向下一步,因此提供合理的默认值是个好主意.(这种提供始终响应预期方法的对象的方式称为Null对象模式.)
同样,在你的例子中,一个空字符串或类似"N/A"的东西,取决于有意义的东西:
user.dig(:user, :address, :street1) || ""
一种方法是结合splat操作符从一些未知文档模型中读取.
some_json = JSON.parse( '{"people": {"me": 6, ... } ...}' ) # => "{"people" => {"me" => 6, ... }, ... } a_bunch_of_args = response.data[:query] # => ["people", "me"] some_json.dig(*a_bunch_of_args) # => 6