最好的红宝石成语为“零或零”

时间:2008-10-16 17:19:55

标签: ruby design-patterns idioms null

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

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

但这看起来很笨拙。

22 个答案:

答案 0 :(得分:65)

对象有nil? method

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

或者,只需一条指令:

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

答案 1 :(得分:31)

如果您真的喜欢最后带问号的方法名称:


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

您的解决方案很好,其他一些解决方案也是如此。

如果你不小心的话,Ruby可以让你搜索一个很好的方法去做所有事情。

答案 2 :(得分:29)

首先,我认为这是您可以检查特定情况的最简洁方式。

其次,对我而言,这是一种代码气味,表明您的设计存在潜在缺陷。通常零和零不应该意味着相同的事情。如果可能的话,你应该尝试在你点击这个代码之前消除val为零的可能性,或者通过检查方法的开头或其他一些机制。

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

答案 3 :(得分:24)

从Ruby 2.3.0开始,您可以将安全导航操作符(&.)与Numeric#nonzero?组合在一起。如果实例为&.nil,则nil会返回nonzero? - 如果数字为0,则会返回unless val&.nonzero? # Is nil or zero end

do_something unless val&.nonzero?

或后缀:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Application;

namespace ConsoleApplication1
{
    class Program
        {
            static void Main(string[] args)
            {
                Program2 program = new Program2();
                //Below I am calling the Test() method knowing that Test() will return a value to save from having to initialize another variable.
                Console.WriteLine("hello world" + program.Test());
            }
        }
    }
    namespace Applicaton
    {

        class Program2
        {
            public int Test()
            {
                int x = 5;
                return x;
            }
        }
    }

答案 4 :(得分:9)

你可以使用Object.nil吗?特别测试nil(而不是在false和nil之间)。您也可以将方法修补为对象。

class Object
   def nil_or_zero?
     return (self.nil? or self == 0)
   end
end

my_object = MyClass.new
my_object.nil_or_zero?
==> false

不建议这样做,因为同事难以跟踪对象的更改,并且可能会使您的代码无法预测。

答案 5 :(得分:4)

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

val.to_i.zero?

但是,如果val是一个不响应#to_i的对象,你将得到一个例外。

答案 6 :(得分:4)

我相信你的代码不正确;它实际上会测试三个值:nil false 和零。这是因为!val表达式对于所有false值都是true,在Ruby中nilfalse

我现在能想到的最好的是

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

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

答案 7 :(得分:3)

我的解决方案还使用了优化条件,减去了条件条件。

module Nothingness
  refine Numeric do
    alias_method :nothing?, :zero?
  end

  refine NilClass do
    alias_method :nothing?, :nil?
  end
end

using Nothingness

if val.nothing?
  # Do something
end

答案 8 :(得分:2)

尽可能地说是惯用语,我建议这样做。

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

由于:

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

答案 9 :(得分:2)

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

答案 10 :(得分:2)

最短且最好的方式应该是

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

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

答案 11 :(得分:1)

简短明了

[0, nil].include?(val)

答案 12 :(得分:0)

如果您愿意,可以使用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

这不是很好的OOP,但它非常灵活且有效。无论如何,我的if通常最终为case

当然Enum.any? / Enum.include?也有用......如果你想变得非常神秘:

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

正确的做法当然是定义方法或功能。或者,如果您必须使用许多值执行相同的操作,请使用这些优秀迭代器的组合。

答案 13 :(得分:0)

我通过定义“是?”来解决这个问题。方法,然后我可以在各种类上实现不同的方法。所以对于Array,“是吗?”表示“尺寸> 0”;对于Fixnum,它意味着“自我!= 0”;对于String,它表示“self!=''”。当然,NilClass定义“是?”就像刚回来一样。

答案 14 :(得分:0)

我非常喜欢Rails blank?方法来处理这类事情,但它不会为true返回0。所以你可以添加你的方法:

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

它将检查某些值是否为0或<:p>

nil.nil_zero?
=> true
0.nil_zero?
=> true
10.nil_zero?
=> false

if val.nil_zero?
  #...
end

答案 15 :(得分:0)

这非常简洁:

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

只要您不介意falsenil相同,它就会起作用。在我所参与的项目中,这种区别只会偶尔发生一次。其余的时间我个人更喜欢跳过.nil?并稍微缩短代码。

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

顺便说一句,我没有使用.zero?,因为如果val是一个字符串,则会引发异常。但如果您知道情况并非如此,那么.zero?会很好。

答案 16 :(得分:0)

而不是猴子修补类,you could use refinements从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
在最后一分钟

Refinements were changed作为范围的文件。所以早期的例子可能已经证明了这一点,但这不起作用。

class Car
  using NilOrZero
end

答案 17 :(得分:0)

对于零和零,评估结果为真:nil.to_s.to_d == 0

答案 18 :(得分:0)

unless (val || 0).zero?

    # do stufff

end

答案 19 :(得分:0)

只需一次拉伸,您就可以做到:

[do_something] if val.to_i == 0

nil.to_i 将返回 0

答案 20 :(得分:-2)

另一种解决方案:

if val.to_i == 0
  # do stuff
end

答案 21 :(得分:-3)

val ||= 0
if val == 0
# do something here
end