I have recently been stumped by the following code:
class Foo
  attr_accessor :n
  def initialize(i)
    @n = i
  end
  def val
    n
  end
  def bump!
    n += 1
  end
end
f = Foo.new(0)
puts f.val
f.bump!
puts f.val succeeds and prints out 0 as expected. f.bump! causes the following NoMethodError
foo.rb:13:in `bump!': undefined method `+' for nil:NilClass (NoMethodError)
        from foo.rb:20:in `<main>'
Any idea why n is nil in the expression n += 1?
Using n = 1 + n instead raises a TypeError (nil cannot be coerced into Fixnum), so n is in fact nil.
Even though you've defined an n= method for Foo, Ruby won't let you call it from within the class without an explicit receiver i.e. self.n=
So when you write n += 1, this gets translated into n = n + 1. n= doesn't have an explicit receiver so Ruby creates a local variable n (which is nil). Thus the n in n + 1 refers to a nil local variable, giving you the NoMethodError.
FYI, you don't need attr_accessor unless you want n to be accessible outside of the class! Even then, when you're writing instance methods, you should just use the normal instance variable @n.
Your error is there :
def bump!
  n += 1
end
Use self.n. Or @n.
When you do :
attr_accessor :n
In fact you do :
def n
  @n
end
def n=(value)
  @n= value
end
And when you do n += 1, you use a local variable (which is niL) instead of using the two methods that were created by the attr_accessor.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With