当 some_method 的返回值为nil时,我发现自己做了很多事情来防止nil。
a = a.some_method.present? ? a.some_method : []
有更多的红宝石方法吗?我尝试过使用
a = []
a ||= a.some_method
但当然只会给我
a = []
谢谢!
答案 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_a
和NilClass#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
返回数组arr
,arr.to_a #=> arr
。 (见Array#to_a。)
如果a.some_method
返回nil
,nil.to_a #=> []
。 (见NilClass#to_a)。