eastafri
eastafri

Reputation: 2226

coercing nil into a number

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

Answers (3)

liwp
liwp

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

Amber
Amber

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

giorgian
giorgian

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

Related Questions