2016-08-02 27 views
1

我发现自己做这个很多,以防止零当返回some_method返回零。替换三元零检查与红宝石的最佳做法

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

有没有更红宝石的方式来做到这一点?我已经使用

a = [] 
a ||= a.some_method 

但ofcourse试图将只给我

a = [] 

的感谢!

+1

'a = a.some_method || []' – Hamms

回答

1

通常的模式是:

result = method(args) || default_value 

||操作者是短路。如果左侧为假,则不会费心评估右侧。在Ruby中,nil被认为是错误的。因此,如果返回nil(或false),则||将评估右侧并作为结果返回。

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

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 # => [] 
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''[ ],......所以我们有便捷to_Xpresence方法方便地躲在方法调用的差异。

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 

我个人认为这是明确的安全包装一个更好的替代方案,在这个线程别处建议。

0

据我所知,a.some_method返回一个数组或nil,并且如果nil您希望它返回一个空数组。如果这是正确的,你可以写:

a.some_method.to_a 

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

如果a.some_method返回nil,nil.to_a #=> []。 (请参阅NilClass#to_a)。