“零或零”的最佳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?
。 &.
如果实例nil
且nonzero?
则返回nil
nonzero?
– 如果这个数字是0
:
unless val&.nonzero? # Is nil or zero end
或者后缀:
do_something unless val&.nonzero?
我相信你的代码是不正确的; 它实际上会testing三个值: nil
, false
和零。 这是因为!val
expression式对于所有错误的值是正确的,在Ruby中是nil
和false
。
我现在能做的最好的是
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
为了尽可能地道,我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?
方法的那种东西,但它不会返回true
为0
。 所以你可以添加你的方法:
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