Checking if a variable is not nil and not zero in ruby
RubyRuby Problem Overview
I am using the following code to check if a variable is not nil and not zero
if(discount != nil && discount != 0)
...
end
Is there a better way to do this?
Ruby Solutions
Solution 1 - Ruby
unless discount.nil? || discount == 0
...
end
Solution 2 - Ruby
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
Beware of the usual disclaimers... great power/responsibility, monkey patching leading to the dark side etc.
Solution 3 - Ruby
ok, after 5 years have passed....
if discount.try :nonzero?
...
end
It's important to note that try
is defined in the ActiveSupport gem, so it is not available in plain ruby.
Solution 4 - Ruby
From Ruby 2.3.0 onward, you can combine the safe navigation operator (&.
) with Numeric#nonzero?
. &.
returns nil
if the instance was nil
and nonzero?
- if the number was 0
:
if discount&.nonzero?
# ...
end
Or postfix:
do_something if discount&.nonzero?
Solution 5 - Ruby
unless [nil, 0].include?(discount)
...
end
Solution 6 - Ruby
You could do this:
if (!discount.nil? && !discount.zero?)
The order is important here, because if discount
is nil
, then it will not have a zero?
method. Ruby's short-circuit evaluation should prevent it from trying to evaluate discount.zero?
, however, if discount
is nil
.
Solution 7 - Ruby
if (discount||0) != 0
#...
end
Solution 8 - Ruby
You can convert your empty row to integer value and check zero?.
"".to_i.zero? => true
nil.to_i.zero? => true
Solution 9 - Ruby
if discount and discount != 0
..
end
update, it will false
for discount = false
Solution 10 - Ruby
You can take advantage of the NilClass
provided #to_i
method, which will return zero for nil
values:
unless discount.to_i.zero?
# Code here
end
If discount
can be fractional numbers, you can use #to_f
instead, to prevent the number from being rounded to zero.
Solution 11 - Ruby
def is_nil_and_zero(data)
data.blank? || data == 0
end
If we pass "" it will return false whereas blank? returns true. Same is the case when data = false blank? returns true for nil, false, empty, or a whitespace string. So it's better to use blank? method to avoid empty string as well.
Solution 12 - Ruby
I prefer using a more cleaner approach :
val.to_i.zero?
val.to_i
will return a 0
if val is a nil
,
after that, all we need to do is check whether the final value is a zero.
Solution 13 - Ruby
Yes, we do have a clean way in ruby.
discount.to_f.zero?
This check handles good amount of cases i.e. discount may be nil, discount may be int 0, discount may be float 0.0, discount may be string "0.0", "0".
Solution 14 - Ruby
When dealing with a database record, I like to initialize all empty values with 0, using the migration helper:
add_column :products, :price, :integer, default: 0
Solution 15 - Ruby
if discount.nil? || discount == 0
[do something]
end
Solution 16 - Ruby
You could initialize discount to 0 as long as your code is guaranteed not to try and use it before it is initialized. That would remove one check I suppose, I can't think of anything else.
Solution 17 - Ruby
Alternative solution is to use Refinements, like so:
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
Solution 18 - Ruby
I believe the following is good enough for ruby code. I don't think I could write a unit test that shows any difference between this and the original.
if discount != 0
end