【发布时间】:2016-06-25 16:02:35
【问题描述】:
在 Rails 中,您可以使用 hash.try(:[], :key),如果 hash 可能是 nil,这会有所帮助。
是否有使用新的 Ruby 2.3 安全导航运算符 &. 和 [] 的等效版本?
【问题讨论】:
标签: ruby-on-rails ruby
在 Rails 中,您可以使用 hash.try(:[], :key),如果 hash 可能是 nil,这会有所帮助。
是否有使用新的 Ruby 2.3 安全导航运算符 &. 和 [] 的等效版本?
【问题讨论】:
标签: ruby-on-rails ruby
&. 不等同于 Rails 的 try,但您可以使用 &. 来表示哈希。随便用,没什么特别的。
hash[:key1]&.[](:key2)&.[](:key3)
虽然我不会那样做。
【讨论】:
&. 和 try 不同。我只考虑hash 是nil 的情况。我最终使用的是hash&.[](:key)
&. 是在 Ruby 2.3 中引入的。
hash&.dig(:key1, :key2, :key3) 看起来更好:)
现在有 Hash#dig 方法可以做到这一点:
重复检索每个键对象对应的值对象。
h = { foo: {bar: {baz: 1}}}
h.dig(:foo, :bar, :baz) #=> 1
h.dig(:foo, :zot) #=> nil
http://ruby-doc.org/core-2.3.0_preview1/Hash.html#method-i-dig
我通常在初始化器中放入类似的东西:
Class Hash
def deep_fetch *args
x = self
args.each do |arg|
x = x[arg]
return nil if x.nil?
end
x
end
end
然后
response.deep_fetch 'PaReqCreationResponse', 'ThreeDSecureVERes', 'Message', 'VERes', 'CH', 'enrolled'
在一个古怪的情况下。
社区的普遍共识似乎是避免尝试和孤独的运营商&.
【讨论】:
dig 非常相似,在 2.3 中引入,就像 &.。有什么不同吗?
Hash 的扩展和prepend 放在一个模块中,而不是直接进行monkeypatch。
Module#prepend 实际修补它将使您能够从以下位置调用super你的猴子补丁来调用你正在覆盖的方法。
h.dig(:foo, :bar, :baz, :bing) 会报错
虽然hash&.[](:key) 对训练有素的 ruby 专家来说很优雅,但我只使用 hash && hash[:key] 因为它对我之后的程序员来说更好更直观,他们可能不熟悉 ruby 的复杂性。代码库中的一些额外字符有时可以为其他人节省大量的谷歌搜索。
(当然,鉴于您要在其中使用它的上下文是在条件语句中。)
【讨论】:
&.[](:key)) 根本无法搜索!另一方面,dig 可以通过使用方式识别为方法;因此,通过搜索ruby method dig,例如,相对容易获得更多信息
使用安全导航运算符比使用hash&.[](:slug) 更清晰的方法是使用fetch 方法:
hash&.fetch(:slug)
如果您的键可能没有定义,您可以使用第二个参数作为默认值:
hash&.fetch(:slug, nil)
【讨论】:
fetch(…, nil),这与#[]完全相同。
当hash 为 nil 时,接受的答案将不予考虑...
您可以在.try 之前使用安全导航运算符重写您拥有的内容,这将起作用
hash&.try(:[], :key)
但你也可以使用:
http://ruby-doc.org/core-2.3.0_preview1/Hash.html#method-i-dig
在哈希上执行此操作的一种方法是...
hash&.dig(:key1, :key2 ...)
如果不存在任何键提取,则返回 nil。
{ key1: { key2: 'info' } }
将返回“信息”
{ key1: { wrong_key: 'info' } }
会返回nil
【讨论】:
hash&.dig( :key1 )。谢谢。