Я использую следующий код, чтобы проверить, если переменная не ноль и не ноль
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.