Я використовую наступний код, щоб перевірити, чи змінна не нульова і не нульова
if(discount != nil && discount != 0)
...
end
Чи є кращий спосіб зробити це?
discountпомилково?
discount.in? [0, nil]що чистіший спосіб можливий
Я використовую наступний код, щоб перевірити, чи змінна не нульова і не нульова
if(discount != nil && discount != 0)
...
end
Чи є кращий спосіб зробити це?
discountпомилково?
discount.in? [0, nil]що чистіший спосіб можливий
Відповіді:
хіба знижка.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, тому він недоступний у звичайному рубіні.
tryметоду.
tryщоб відобразити альтернативний варіант (саме тому це було сприйнято в першу чергу!), Якщо це зрозуміло читача, який ActiveSupportне ванільний рубін.
якщо [нуль, 0]. включити? (знижка) # ... кінець
З Ruby 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
Якщо ми передамо "", вона поверне помилкову, тоді як порожню? повертає правду. Той самий випадок, коли дані = помилкові порожні? повертає true для нуля, false, порожнього чи рядка пробілів. Тож краще використовувати бланк? метод, щоб уникнути порожнього рядка.
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.