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
我没有使用三重嵌套的平面数组有什么实际的例子可以说明这一点?
更新
这些方法解决了最常见的Ruby问题之一下面的问题大约有20个副本,都是通过使用
dig
解决的:How to avoid NoMethodError for missing elements in nested hashes, without repeated nil checks?
Ruby Style: How to check whether a nested hash element exists
最佳答案
在我们的例子中,由于引用而导致的NoMethodError
s是我们在生产环境中看到的最常见的错误。
新的nil
允许您在访问嵌套元素时省略Hash#dig
检查由于散列最适合用于数据结构未知或不稳定的情况,因此获得官方支持非常有意义。
让我们以你为例。以下内容:
user.dig(:user, :address, :street1)
不等于:
user[:user][:address][:street1]
在
nil
或user[:user]
是user[:user][:address]
的情况下,这将导致运行时错误。相反,它相当于下面这个成语:
user[:user] && user[:user][:address] && user[:user][:address][:street1]
请注意,将在其他地方创建的符号列表传递到
nil
中是很简单的,而从这样的列表中重新创建后一个构造则不是很简单。Hash#dig
允许您轻松地进行动态访问,而无需担心Hash#dig
引用。显然
nil
也要短得多。需要注意的一点是,如果有任何键被证明是,那么
Hash#dig
本身就会返回Hash#dig
,这可能会导致同一类错误,因此最好提供一个合理的默认值。(这种提供始终响应所需方法的对象的方法称为Null Object Pattern)同样,在您的示例中,空字符串或类似“N/A”的内容取决于什么是有意义的:
user.dig(:user, :address, :street1) || ""