用ruby最佳实践取代三元零检查

时间:2016-08-02 01:29:40

标签: ruby-on-rails ruby

some_method 的返回值为nil时,我发现自己做了很多事情来防止nil。

a = a.some_method.present? ? a.some_method : []

有更多的红宝石方法吗?我尝试过使用

a = []
a ||= a.some_method

但当然只会给我

a = []

谢谢!

5 个答案:

答案 0 :(得分:3)

通常的模式是:

result = method(args) || default_value

||运营商正在短路。如果左侧是假的,则不会费心去评估右侧。在Ruby中,nil被认为是假的。因此,如果返回nil(或false),则||会评估右侧并将其作为结果返回。

请注意左侧和右侧的顺序很重要。

答案 1 :(得分:1)

你已经得到了一些好的答案。另一种方法 - 如果这是你自己的代码中的一个问题 - 就是在Ruby的标准库之后对你的类进行建模,例如: Hash#fetch,因此用户只需提供一个带有表达式的块即可用作默认值。

class Whatever
  def some_method
    result = nil # normally this would be computed
    return result unless result.nil?
    yield if block_given?
  end
end

我明确核对nil?的原因是result可以合法false的情况。如果您不关心这一点,或者您知道它不会发生变化,请随时改变条件(例如unless result)。

用法:

Whatever.new.some_method
#=> nil
Whatever.new.some_method { [] }
#=> []
Whatever.new.some_method { 1 + 1 }
#=> 2

我个人认为这是本线程中其他地方建议的显式安全包装的更好的替代方法。

答案 2 :(得分:0)

如果您发现自己需要使用相同方法的ternany或类似模式超过一次或两次,您可能需要考虑引入“安全”变体。

class A

  def some_method
    nil
  end

  def some_method_safe
    if value = self.some_method
      value
    else
      []
    end
  end

end

A.new.some_method_safe # => []

答案 3 :(得分:0)

大概你的some_method会返回一个数组或nil。如果some_method发送的内容不是present?''false{}[]nil)然后你手上有一个非常奇怪的界面。我认为!x.present?比你需要的更广泛。

我猜你的逻辑更像是:

x = a.some_method
x = [ ] if(x.nil?)

所以你真正要做的就是将nil变成一个空数组并单独留下一个数组。 Array#to_aNilClass#to_a就是这样,您可以简单地说:

x = a.some_method.to_a

Array#to_a的问题在于它不能很好地处理Array子类,但这是一个非常罕见的问题。

在某些情况下,“不存在”意味着nil,而在其他情况下意味着0''[ ],......所以我们有方便{{1}和presence方法可以方便地隐藏方法调用背后的差异。

答案 4 :(得分:0)

我知道a.some_method会返回一个数组或nil,如果nil则要返回一个空数组。如果这是正确的,你可以写:

a.some_method.to_a

如果a.some_method返回数组arrarr.to_a #=> arr。 (见Array#to_a。)

如果a.some_method返回nilnil.to_a #=> []。 (见NilClass#to_a)。