Reputation: 2226
What is happening here??
irb(main):001:0> a= nil
=> nil
irb(main):002:0> b = nil
=> nil
irb(main):003:0> a
=> nil
irb(main):004:0> a+b
NoMethodError: undefined method `+' for nil:NilClass
from (irb):4
from :0
irb(main):005:0> if a.nil? or b.nil?; a,b=0;end;
irb(main):006:0* c = a+b
TypeError: nil can't be coerced into Fixnum
from (irb):6:in `+'
from (irb):6
from :0
irb(main):007:0>
How can you safely perform arithmetic by transforming nil to an number?
Upvotes: 3
Views: 834
Reputation: 6926
Your parallel assignment (a, b = 0
) results in a=0
and b=nil
, i.e. it assigns 0
to a
and nil
to b
, because there is only one value on the right hand side.
What you want is: if a.nil? or b.nil?; a = b = 0; end c = a + b
Obviously the code is still broken, since you overwrite any non-nil values of a
and b
with 0 when a
or b
is nil.
Upvotes: 3
Reputation: 526803
Why would you want to add nil
? It's specifically designed to be something that represents the lack of a value (note: nil
is NOT 0
).
If what you're actually wanting to do is set both values to 0
if either is currently nil
, then what you actually want is this:
if a.nil? or b.nil?; a,b=0,0; end
Your mistake in the code above was the a,b=0
portion, which only sets the value of a
to 0
- it sets b
to nil
because the left hand side is looking for two values, and only one is provided on the right (so the others are assumed to be nil
).
Upvotes: 3
Reputation: 3825
Depending on why there's a nil instead of a number, you could decide that it's good for you to consider nil as 0; in that case, you can do something like:
c = (a || 0) + (b || 0)
This, of course, only makes sense if you know why you have a nil instead of a number...
Upvotes: 5