“零或零”的最佳ruby成语

我正在寻找一个简洁的方式来检查一个值,看看它是零还是零。 目前我正在做类似的事情:

if (!val || val == 0) # Is nil or zero end 

但是这似乎很笨拙。

对象有一个零? 方法 。

 if val.nil? || val == 0 [do something] end 

或者,只需一条指令:

 [do something] if val.nil? || val == 0 

如果你最后真的很喜欢带有问号的方法名:

if val.nil? || val.zero? # do stuff end
if val.nil? || val.zero? # do stuff end 

你的解决scheme是好的,其他一些解决scheme也是如此。

如果你不小心,Ruby可以让你search一个可以做所有事情的好方法。

首先,我认为这是最简洁的方式,你可以检查特定的条件。

其次,对我来说,这是一种代码味道,表明您的devise中存在潜在的缺陷。 一般零和零不应该是一样的东西。 如果可能的话,你应该尝试消除在你打这个代码之前val不可能为零的可能性,或者通过在方法开始时检查或者其他一些机制。

在这种情况下,你可能有一个完全合法的理由,在这种情况下,我认为你的代码是好的,但是如果可能的话,我至less会考虑试图摆脱零检查。

你可以使用Object.nil? 专门testing零(而不是陷入虚假和零之间)。 您也可以将一种方法猴子修补到Object中。

 class Object def nil_or_zero? return (self.nil? or self == 0) end end my_object = MyClass.new my_object.nil_or_zero? ==> false 

不推荐这样做,因为对同事的更改难以跟踪同事,并且可能使其他人无法预知您的代码。

从Ruby 2.3.0开始,您可以将安全导航运算符( &. )与Numeric#nonzero?&. 如果实例nilnonzero?则返回nil nonzero? – 如果这个数字是0

 unless val&.nonzero? # Is nil or zero end 

或者后缀:

 do_something unless val&.nonzero? 

我相信你的代码是不正确的; 它实际上会testing三个值: nilfalse和零。 这是因为!valexpression式对于所有错误的值是正确的,在Ruby中是nilfalse

我现在能做的最好的是

 if val == nil || val == 0 # do stuff end 

哪一个当然不是很聪明,但(非常)清楚。

nil.to_i返回零,所以我经常这样做:

 val.to_i.zero? 

但是,如果val永远不是respond_to #to_i的对象,您将会得到一个exception。

Rails通过属性查询方法来做到这一点,除了false和nil,0和“”也计算为false。

 if (model.attribute?) # => false if attribute is 0 and model is an ActiveRecord::Base derivation 

然而它有一些诋毁者。 http://www.joegrossberg.com/archives/002995.html

为了尽可能地道,我build议这个。

 if val.nil? or val == 0 # Do something end 

因为:

  • 它使用零? 方法。
  • 它使用“或”运算符,这比||更好。
  • 它不使用括号,在这种情况下不需要使用括号。 括号只能用于某些目的,比如覆盖某些运营商的优先级。

最短和最好的方式应该是

if val&.>(0) # do something end

对于val&.>(0) ,当val为零时返回nil,因为>基本上也是一种方法,在ruby中nil等于false。 当val == 0时它返回false。

简短明了

[0, nil].include?(val)

我通过定义一个“是”来处理这个问题 方法,然后我可以在不同的类上实现不同的方法。 所以对于arrays,“是吗?” 指“大小> 0”; Fixnum意思是“self!= 0”; 对于string,它的意思是“self!=''”。 当然,NilClass定义“是? 只是返回零。

我刚刚删除了我以前的答案。 我误解了你,并build议使用#blank? 方法。

无论哪种方式,我会扩展Object类,并为此创build一个方法。

如果你喜欢,你可以使用case

  case val with nil, 0 # do stuff end 

那么你可以使用===东西,有时候这很好。 或者做这样的事情:

 not_valid = nil, 0 case val1 with *not_valid # do stuff end #do other stuff case val2 with *not_valid, false #Test for values that is nil, 0 or false # do other other stuff end 

这不是完美的面向对象,但它非常灵活,它的工作原理。 无论如何, if我通常最终成为case

当然Enum.any? / Enum.include? 也有一些作品…如果你喜欢变得非常神秘:

 if [0, nil].include? val #do stuff end 

正确的做法当然是定义一个方法或函数。 或者,如果你必须用许多值来做同样的事情,那么使用这些好的迭代器的组合。

我真的很喜欢Rails的blank? 方法的那种东西,但它不会返回true0 。 所以你可以添加你的方法:

 def nil_zero? if respond_to?(:zero?) zero? else !self end end 

它会检查一些值是零还是0:

 nil.nil_zero? => true 0.nil_zero? => true 10.nil_zero? => false if val.nil_zero? #... end 

而不是猴子修补类, 你可以使用从Ruby 2.1开始的改进 。 改进类似于猴子修补; 在那里,他们允许你修改这个类,但是这个修改仅限于你希望使用它的范围。

如果你想做这个检查一次,这是矫枉过正的,但如果你重复自己这是一个伟大的替代猴子修补。

 module NilOrZero refine Object do def nil_or_zero? nil? or zero? end end end using NilOrZero class Car def initialize(speed: 100) puts speed.nil_or_zero? end end car = Car.new # false car = Car.new(speed: nil) # true car = Car.new(speed: 0) # true 

优化在最后一刻被改变 ,以限定到文件。 所以前面的例子可能已经certificate了这一点,这是行不通的。

 class Car using NilOrZero end 

对于零和零,这个计算结果为真: nil.to_s.to_d == 0

这非常简洁:

 if (val || 0) == 0 # Is nil, false, or zero. end 

只要你不介意把false当作nil 。 在我所做的项目中,这个区别只是偶尔一次。 剩下的时间我个人更喜欢跳过.nil? 并且代码略短。

[ 更新 :我不再写这种东西了。 它的作品,但太神秘了。 我试图通过改变我所做的几个地方来纠正我的错误。]

顺便说一下,我没有使用.zero? 因为如果val是一个string,这会引发一个exception。 但是.zero? 如果你知道事实并非如此,那就没问题了。

另一个scheme

 if val.to_i == 0 # do stuff end 
 val ||= 0 if val == 0 # do something here end