Я использую следующий код, чтобы проверить, если переменная не ноль и не ноль
if(discount != nil && discount != 0)
...
end
Есть лучший способ сделать это?
discount
ложь?
discount.in? [0, nil]
что более чистый способ возможен
Я использую следующий код, чтобы проверить, если переменная не ноль и не ноль
if(discount != nil && discount != 0)
...
end
Есть лучший способ сделать это?
discount
ложь?
discount.in? [0, nil]
что более чистый способ возможен
Ответы:
разве что discount.nil? || скидка == 0 # ... конец
The and and or keywords are banned. It's just not worth it. Always use && and || instead.
. И это правильно по причинам Дэвида и Тома.
class Object
def nil_zero?
self.nil? || self == 0
end
end
# which lets you do
nil.nil_zero? # returns true
0.nil_zero? # returns true
1.nil_zero? # returns false
"a".nil_zero? # returns false
unless discount.nil_zero?
# do stuff...
end
Остерегайтесь обычных заявлений об отказе от ответственности ... великой власти / ответственности, исправлений обезьян, ведущих на темную сторону и т. Д.
хорошо, через 5 лет прошло ....
if discount.try :nonzero?
...
end
Важно отметить, что try
он определен в геме ActiveSupport, поэтому он недоступен в обычном ruby.
try
метода.
try
чтобы показать альтернативный вариант (именно поэтому он был отклонен в первую очередь!), При условии, что это ясно для читатель, который ActiveSupport
не ванильный рубин.
если только [nil, 0] .include? (скидка) # ... конец
Начиная с версии 2.3.0, вы можете комбинировать оператор безопасной навигации ( &.
) с Numeric#nonzero?
. &.
возвращает, nil
если экземпляр был nil
и nonzero?
- если число было 0
:
if discount&.nonzero?
# ...
end
Или постфикс:
do_something if discount&.nonzero?
"foo"&.nonzero? # => NoMethodError: undefined method 'nonzero?' for "foo":String
.... Это не безопасно использовать на произвольных объектах.
nil
.
nonzero?
- если номер был 0
" . Также необходимость проверять, возникает ли совершенно произвольный объект 0
крайне редко по сравнению с тем, чтобы проверять число, которое может или не может быть nil
. Следовательно, это почти подразумевается. Даже если кто-то делает противоположное предположение, он сразу же поймет, что происходит, когда попытается его выполнить.
Вы могли бы сделать это:
if (!discount.nil? && !discount.zero?)
Здесь важен порядок, потому что если discount
есть nil
, то у него не будет zero?
метода. Оценка Руби по короткому замыканию должна препятствовать тому, чтобы он пытался оценить discount.zero?
, однако, если discount
есть nil
.
if discount and discount != 0
..
end
обновить, это будет false
дляdiscount = false
Вы можете воспользоваться NilClass
предоставленным #to_i
методом, который будет возвращать ноль для nil
значений:
unless discount.to_i.zero?
# Code here
end
Если это discount
могут быть дробные числа, вы можете использовать #to_f
вместо них, чтобы предотвратить округление числа до нуля.
"".to_i == "foo".to_i == "0".to_i == 0
, Ваш метод сделает все виды непреднамеренных приведения типов. Он также потерпит неудачу, NoMethodError
если discount
не отвечает to_i
.
def is_nil_and_zero(data)
data.blank? || data == 0
end
Если мы передадим "", он вернет false, тогда как пусто? возвращает истину. То же самое в случае, когда data = false blank? возвращает true для nil, false, empty или строки пробела. Так что лучше использовать бланк? метод, чтобы избежать пустой строки.
blank?
это метод для рельсов, недоступный в ванильном рубине.
if discount.nil? || discount == 0
[do something]
end
Альтернативное решение - использовать уточнения, например:
module Nothingness
refine Numeric do
alias_method :nothing?, :zero?
end
refine NilClass do
alias_method :nothing?, :nil?
end
end
using Nothingness
if discount.nothing?
# do something
end
Я считаю, что следующее достаточно для рубинового кода. Я не думаю, что смогу написать модульный тест, который показал бы разницу между этим и оригиналом.
if discount != 0
end
true
если бы были скидки nil
.