Лучший рубин идиома для "ноль или ноль" - PullRequest
72 голосов
/ 16 октября 2008

Я ищу краткий способ проверить значение, чтобы увидеть, является ли оно ноль или ноль. В настоящее время я делаю что-то вроде:

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

Но это кажется очень неуклюжим.

Ответы [ 21 ]

2 голосов
/ 20 октября 2008

Чтобы быть настолько идиоматичным, насколько это возможно, я бы предложил это.

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

Потому что:

  • Использует ноль? способ.
  • Используется оператор "или", который предпочтительнее, чем ||.
  • Он не использует скобки, которые не нужны в этом случае. Скобки следует использовать только в тех случаях, когда они служат какой-либо цели, такой как переопределение приоритета определенных операторов.
1 голос
/ 15 октября 2016

Коротко и ясно

[0, nil].include?(val)

0 голосов
/ 21 января 2015

Вместо того, чтобы вносить исправления в класс, вы можете использовать уточнения , начиная с 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

Уточнения были изменены в последнюю минуту, чтобы охватить файл. Так что более ранние примеры могли показать это, но это не сработает.

class Car
  using NilOrZero
end
0 голосов
/ 25 сентября 2014

Это очень лаконично:

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

Это работает до тех пор, пока вы не возражаете относиться к false так же, как nil. В проектах, над которыми я работал, это различие имеет значение только время от времени. В остальное время я лично предпочитаю пропустить .nil? и иметь немного более короткий код.

[ Обновление : я больше такого не пишу. Это работает, но слишком загадочно. Я попытался исправить свои проступки, изменив несколько мест, где я это сделал.]

Кстати, я не использовал .zero?, поскольку это вызывает исключение, если val это, скажем, строка. Но .zero? было бы хорошо, если бы вы знали, что это не так.

0 голосов
/ 13 февраля 2010

Мне действительно нравится метод 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
0 голосов
/ 17 октября 2008

Я имею дело с этим, определяя "есть?" метод, который я затем могу реализовать по-разному на разных классах. Так что для Array, "есть?" означает «размер> 0»; для Fixnum это означает «self! = 0»; для String это означает "self! = ''". NilClass, конечно, определяет "есть?" как только вернул ноль.

0 голосов
/ 05 ноября 2008
val ||= 0
if val == 0
# do something here
end
0 голосов
/ 15 марта 2017

Это значение равно true для нуля и нуля: nil.to_s.to_d == 0

0 голосов
/ 26 января 2009

Вы можете использовать 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 s обычно заканчиваются как case s в любом случае.

Конечно, Enum.any? / Enum.include? тоже вроде работает ... если вы хотите по-настоящему загадочно сказать:

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

Что нужно сделать, это, конечно, определить метод или функцию. Или, если вам нужно сделать то же самое со многими значениями, используйте комбинацию этих хороших итераторов.

0 голосов
/ 08 января 2019
unless (val || 0).zero?

    # do stufff

end
...