【问题标题】:effectively applying nil check in ruby有效地在 ruby​​ 中应用 nil 检查
【发布时间】:2020-07-01 07:08:07
【问题描述】:

我有这个代码

args = x.lead_details.last.leads.last.country_id rescue nil
Function(args)

我使用了 rescue 关键字来确保我不会收到类似的错误

 undefined method `country_id' for nil:NilClass,
 undefined method `leads' for nil:NilClass

有没有更好的方法可以实现这一点?

其他方法是

Function(x.lead_details.last.leads.last.country_id if x.present? && x.lead_details.present? && x.lead_details.last? && so on)

【问题讨论】:

  • 只是好奇:Function 是做什么的(我在 docs 中没有找到它),以及根据什么语法规则可以将 rescue 作为表达式的一部分传递?我可以在这个地方也使用ensure 吗?
  • “函数”是随机函数的名称。
  • 但是你如何管理在参数列表中有一个rescue?当我尝试这个时,我得到一个语法错误。
  • @user1934428 这很可能是伪代码 - 您不能在参数列表中使用救援和“内联救援” - 例如不应使用 foo(bar) rescue SomeErrorthoughtbot.com/blog/don-t-inline-rescue-in-ruby
  • @max : 非常有趣 .... 伪代码导致真正的 Ruby 错误消息。 code0079:如果您想讨论具体问题,请同时发布您的具体代码,而不是发明自己的语法。

标签: ruby-on-rails ruby exception rescue


【解决方案1】:

rescue nil 是邪恶的。它不只是挽救零错误。它会吃掉你扔给它的所有东西。例如:

class Foo
  def bar
  end

  def woo
    raise ArgumentError
  end
end

Foo.new.baz rescue nil # nil!
Foo.new.woo rescue nil # nil!

这适用于任何inline rescue

Ruby 2.3.0 引入了安全导航运算符,让您可以:

x&.lead_details&.last&.leads&.last&.country_id

ActiveSupport 也有一个 Object#try!可以在旧版本的 Ruby 中使用的方法:

x.try!(:lead_details).try!(:last).try!(:leads).try!(:last).try!(:country_id)

但是你真的只是在这里对得墨忒耳定律感到生气,你应该重构代码,这样你就不必遍历那个疯狂的方法链,因为你实际上只是在埋葬大量潜在的错误并使调试变得不可能.

见:

【讨论】:

    【解决方案2】:

    您可以使用 Ruby 2.3 中引入的safe navigation operator (&.):

    Function(x&.lead_details&.last&.leads&.last&.country_id)
    

    当您尝试调用 nil 上的方法时,它会返回 nil

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-02-14
      • 1970-01-01
      • 2012-09-07
      • 1970-01-01
      • 2013-09-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多