I have the following Ruby code that throws the same exception depending on whether a variable in the constructor is set via the @foo instance variable or via the foo= method of attr_accessor:
# Variation 1: initializing @foo, using foo
class A
attr_accessor :foo
def initialize
@foo = [0,1,2] # <<-- With @
foo += [3] # NoMethodError: undefined method `+' for nil:NilClass
end
end
a = A.new
I presume this variation 1 is some kind of manifestation of the "assigning a non existant variable to itself is nil in Ruby". And somehow the variable declaration takes precedence over the generated method foo.
non_existant += [1] # NoMethodError: undefined method `+' for nil:NilClass
So I decided to only use the methods generated by attr_accessor. And by doing this, I suddenly seem to have introduced a local variable in the constructor:
# Variation 2: initializing with foo=, using foo
class A
attr_accessor :foo
def initialize
foo = [0,1,2] # <<-- No @
foo += [3]
end
end
a = A.new
puts a.foo.inspect # prints nil
a.foo += [4] # NoMethodError: undefined method `+' for nil:NilClass
For the record: I am aware that using only the @foo instance variable in the constructor fixes the issue:
# Variation 2: Only using @foo
class A
attr_accessor :foo
def initialize
@foo = [0,1,2]
@foo += [3]
end
end
a = A.new
puts a.foo.inspect # prints [0, 1, 2, 3]
a.foo += [4] # works
But as soon as I use the foo= method generated by attr_accessor, the instance should be properly saved and I don't understand why I can't access it on an instance?