【问题标题】:Ruby one line if statement with exception handlingRuby 一行 if 语句与异常处理
【发布时间】:2014-10-24 07:15:28
【问题描述】:

我似乎找不到办法做到这一点。 我想要做的就是尝试第一个语句,如果它是空白或空(在任何阶段)然后返回另一个。比如

a.b.c.blank? ? a.b.c : 'Fill here'

这导致我出现nil:NillClass 异常。有没有办法以简单的单线方式解决这个问题?

【问题讨论】:

  • 你可以看看andand..
  • 如果您发现至少有一个答案有帮助,请考虑选择您最喜欢的一个。

标签: ruby exception-handling ternary-operator


【解决方案1】:

如果你有active_support可用,你可以使用Object#try

a.try(:b).try(:c) or 'Fill here'

如果你没有这个,很容易给 Object 打补丁来添加一个。这是active_support 中的代码,在您使用try 方法之前将其放在某个位置。

class Object
  def try(*a, &b)
    if a.empty? && block_given?
      yield self
    else
      public_send(*a, &b) if respond_to?(a.first)
    end
  end
end

之后就可以使用了:

a = nil
a.try(:b).try(:c).try(:nil?)    #=> true

b = 1
b.try(:+, 2)    #=> 3

【讨论】:

    【解决方案2】:

    默认不抛出nil:NilClass异常。

    abc 可能为 nil,因此对于一行语句,您可以这样做:

    # require this to use present?, not needed with rails
    require 'active_support/all'
    
    a.present? ? (a.b.present? ? (a.b.c.present? ? a.b.c : 'Fill here') : 'Fill here') : 'Fill here'
    

    (这是三元表达式,不完全是 if 语句)

    但这很难看,尽管如果您确定 aa.b 永远不是 nil,则可以删除部分表达式。​​

    我使用present? 而不是blank? 来保持与您的表达相同的顺序。如果条件为真,三元运算符会计算第一个表达式,所以这可能是您的错误。

    【讨论】:

    • 这是一种嵌套方式。如果我有很深的东西怎么办?
    • 那就不要在一行中做,或者之前检查你的对象是否不是nil。基本条件就是var.present? ? var : 'default value'
    【解决方案3】:

    我需要允许使用 presence 的 ActiveSupport 包,执行如下操作:

    require 'active_support'
    require 'active_support/core_ext/object/blank'
    a.presence && a.b.presence && a.b.c.presence || 'Fill here'
    

    见:http://apidock.com/rails/Object/presence

    【讨论】:

    • 我不了解 Rails,但怀疑您可以这样做:[a,b,c,..].reduce(?) { |e| (e ||= ?) ... }。只是思考的食物。
    【解决方案4】:

    由于 Ruby 2.3.0(2015-12-25 发布),这可以使用 save navigation operator 实现,类似于 Groovy 和 Kotlin 的 null safe ?

    新的方法调用语法,object&.foo', method foo is called onobject' 如果不是 nil。

    # a as object { b: { c: 'foobar' } }
    a&.b&.c&.empty? ? 'Fill here' : a.b.c #=> 'foobar'
    nil&.b&.c&.empty? ? 'Fill here' : a.b.c #=> 'Fill here'
    

    安全调用在调用 nil 对象时返回 nil。这就是为什么上面示例中的第二种情况计算结果为nil,因此计算结果为false

    来源:NEWS for Ruby 2.3.0 (Feature #11537)
    另见:What is the difference between try and &. (safe navigation operator) in Ruby

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-04-15
      • 2016-04-21
      • 2014-02-15
      • 1970-01-01
      • 1970-01-01
      • 2012-12-31
      • 1970-01-01
      相关资源
      最近更新 更多