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?
This question is related to
ruby
unless discount.nil? || discount == 0 # ... end
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.
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.
if discount and discount != 0
..
end
update, it will false
for discount = false
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".
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
unless [nil, 0].include?(discount) # ... end
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?
if (discount||0) != 0
#...
end
if discount.nil? || discount == 0
[do something]
end
if (discount||0) != 0
#...
end
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.
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.
if (discount||0) != 0
#...
end
You can convert your empty row to integer value and check zero?.
"".to_i.zero? => true
nil.to_i.zero? => true
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.
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
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.
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.
if (discount||0) != 0
#...
end
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.
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".
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
.
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?
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.
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.
unless [nil, 0].include?(discount) # ... end
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
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.
if discount.nil? || discount == 0
[do something]
end
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
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
if discount and discount != 0
..
end
update, it will false
for discount = false
unless [nil, 0].include?(discount) # ... end
You can convert your empty row to integer value and check zero?.
"".to_i.zero? => true
nil.to_i.zero? => true
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
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.
unless [nil, 0].include?(discount) # ... end
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
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
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.
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
.
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.
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.
Source: Stackoverflow.com