Ruby 中的 `try` 和 `&.`(安全导航运算符)有什么区别
What is the difference between `try` and `&.` (safe navigation operator) in Ruby
这是我的代码:
class Order < Grape::Entity
expose :id { |order, options| order.id.obfuscate }
expose :time_left_to_review do |order, options|
byebug
order&.time_left_to_review # ERROR
end
expose :created_at { |order, options| order.last_transition.created_at }
end
# NoMethodError Exception: undefined method `time_left_to_review' for #<Order:0x007f83b9efc970>
我以为 &.
是 .try
的快捷方式,但我想我错了。有人可以指出我所缺少的正确方向吗?
我觉得这与 ruby 无关。也许是葡萄?虽然我不明白这是怎么回事。
try
方法忽略了很多事情,它只是试一试,如果事情不成功就收工。
&
条件导航选项将仅 阻止对nil
对象的调用。任何其他内容均被视为有效,并将承担全部后果,包括例外情况。
&.
的工作方式类似于 #try!
,而不是 #try
。
这里是 #try!
的描述(来自 documentation):
Same as #try, but will raise a NoMethodError exception if the receiving is not nil and does not implemented the tried method.
所以基本上它可以避免您在 nil
上调用方法,但是如果出现一个对象,它会像往常一样尝试调用它的方法。
引用自Rails文档,所以强调一下很重要
Ruby 不提供 #try
;它由 Rails 或更准确地说是 ActiveSupport 提供。然而,safe navigation operator (&.
) 是 Ruby 2.3.0.
中提供的语言功能
我来这里有点晚了,其他答案已经涵盖了它是如何工作的,但我想补充一些其他答案没有涵盖的内容。
您的问题是 Ruby 中的 try
和 &.
有什么区别。 Ruby 是这里的关键词。
最大的区别是Ruby中没有try
,它是Rails提供的方法。如果您在 rails 控制台中执行类似操作,您可以看到这个或您自己:
[1, 2, 3].try(:join, '-')
#=> "1-2-3"
然而,如果您在 irb 控制台中执行相同的操作,您将得到:
[1, 2, 3].try(:join, '-')
NoMethodError: undefined method `try' for [1, 2, 3]:Array
&.
是 Ruby 标准库的一部分,因此可用于任何 Ruby 项目,而不仅仅是 Rails。
除了上述答案外,我正在添加一些示例。1
account = Account.new(owner: Object.new)
account.try(:owner).try(:address)
# => nil
account&.owner&.address
# => NoMethodError: undefined method `address' for #<Object:0x00559996b5bde8>`
account.try!(:owner).try!(:address)
# => NoMethodError: undefined method `address' for #<Object:0x00559996b5bde8>`
正如我们所见,try
不检查接收者是否响应给定的方法。而 try!
和 &.
的行为相同。如果接收方响应 address
方法,则所有接收方都会 return 相同的结果。我更喜欢使用 &.
,因为它看起来更干净。
有关安全导航运算符 (&.) 的更多信息,我发现此博客非常有用 https://mitrev.net/ruby/2015/11/13/the-operator-in-ruby/
这是我的代码:
class Order < Grape::Entity
expose :id { |order, options| order.id.obfuscate }
expose :time_left_to_review do |order, options|
byebug
order&.time_left_to_review # ERROR
end
expose :created_at { |order, options| order.last_transition.created_at }
end
# NoMethodError Exception: undefined method `time_left_to_review' for #<Order:0x007f83b9efc970>
我以为 &.
是 .try
的快捷方式,但我想我错了。有人可以指出我所缺少的正确方向吗?
我觉得这与 ruby 无关。也许是葡萄?虽然我不明白这是怎么回事。
try
方法忽略了很多事情,它只是试一试,如果事情不成功就收工。
&
条件导航选项将仅 阻止对nil
对象的调用。任何其他内容均被视为有效,并将承担全部后果,包括例外情况。
&.
的工作方式类似于 #try!
,而不是 #try
。
这里是 #try!
的描述(来自 documentation):
Same as #try, but will raise a NoMethodError exception if the receiving is not nil and does not implemented the tried method.
所以基本上它可以避免您在 nil
上调用方法,但是如果出现一个对象,它会像往常一样尝试调用它的方法。
引用自Rails文档,所以强调一下很重要
Ruby 不提供 #try
;它由 Rails 或更准确地说是 ActiveSupport 提供。然而,safe navigation operator (&.
) 是 Ruby 2.3.0.
我来这里有点晚了,其他答案已经涵盖了它是如何工作的,但我想补充一些其他答案没有涵盖的内容。
您的问题是 Ruby 中的 try
和 &.
有什么区别。 Ruby 是这里的关键词。
最大的区别是Ruby中没有try
,它是Rails提供的方法。如果您在 rails 控制台中执行类似操作,您可以看到这个或您自己:
[1, 2, 3].try(:join, '-')
#=> "1-2-3"
然而,如果您在 irb 控制台中执行相同的操作,您将得到:
[1, 2, 3].try(:join, '-')
NoMethodError: undefined method `try' for [1, 2, 3]:Array
&.
是 Ruby 标准库的一部分,因此可用于任何 Ruby 项目,而不仅仅是 Rails。
除了上述答案外,我正在添加一些示例。1
account = Account.new(owner: Object.new)
account.try(:owner).try(:address)
# => nil
account&.owner&.address
# => NoMethodError: undefined method `address' for #<Object:0x00559996b5bde8>`
account.try!(:owner).try!(:address)
# => NoMethodError: undefined method `address' for #<Object:0x00559996b5bde8>`
正如我们所见,try
不检查接收者是否响应给定的方法。而 try!
和 &.
的行为相同。如果接收方响应 address
方法,则所有接收方都会 return 相同的结果。我更喜欢使用 &.
,因为它看起来更干净。
有关安全导航运算符 (&.) 的更多信息,我发现此博客非常有用 https://mitrev.net/ruby/2015/11/13/the-operator-in-ruby/