Missing @ for instace variable in class, but no error message

Some days ago I was defining a class, but forgot to use the leading @
for an instance variable. But it still works – that variable was made
accessible by attr_accessor statement. So my question:

Why gives the statement “puts a” no error message? In my opinion it
should give one, I forgot to use @. The “attr_accessor :a” was only
there to allow access from outside of that class, for instance
variables.

#!/usr/bin/ruby -w
class Test
attr_accessor :a
def initialize
@a = 0
@b = 1
end
def show_values
puts a # should be @a, but seems to work
puts b # gives an error, as expected
end
end
t = Test.new
t.show_values

Output is:
ruby --version
ruby 1.8.7 (2010-08-16 patchlevel 302) [x86_64-linux]

ruby test.rb
0
test.rb:11:in show_values': undefined local variable or methodb’ for
#<Test:0x7f85f99c02f8 @b=1, @a=0> (NameError)
from test.rb:16

Best regards,

Stefan S.

attr_accessor defines the Test#a method which is a getter for the @a
instance variable

attr_accessor actually defines a public instance method, named ‘a’. That
method can be called from both inside and outside the class. So, it’s
not an
error, it’s perfectly valid.

On 10/6/2010 5:42 PM, Andrew W. wrote:

attr_accessor actually defines a public instance method, named ‘a’. That
method can be called from both inside and outside the class. So, it’s not an
error, it’s perfectly valid.

Beware of attempting to use the bare a= accessor within an instance
method though. That will instead cause a variable named “a” to be
created with the the method’s scope rather than use the a= accessor, so
@a won’t be updated as expected. If you want to use the a= accessor,
you need to use self.a = whatever. e.g.:

class MyClass
attr_accessor :a

def change_a_bad(value)
a = value
end

def change_a_good(value)
self.a = value
end
end

my_class = MyClass.new
my_class.a = 1

my_class.change_a_bad(2)
my_class.a # => 1 !!!

my_class.change_a_good(2)
my_class.a # => 2 :slight_smile:

-Jeremy

On 10/06/2010 10:17 PM, John S. wrote:

people use ‘self.some_method’ instead of just ‘some_method’?".

I knew that I had a lot of redundant 'self’s and a few days ago I got
around to removing them in a script. As Jeremy points out, leaving off
‘self’ in ‘some_method=’ results in the creation of the variable
‘some_method’, as testing showed.

Thanks go to Dave T., Chad F., Andy H., and their book
“Programming Ruby” – my introduction to Ruby. :slight_smile:

-Jeremy

Jeremy B. wrote:

Beware of attempting to use the bare a= accessor within an instance
method though. That will instead cause a variable named “a” to be
created with the the method’s scope rather than use the a= accessor, so
@a won’t be updated as expected. If you want to use the a= accessor,
you need to use self.a = whatever. e.g.:

Jeremy raises an excellent point. I wish I had read this post a few days
ago. A few weeks ago, someone asked the question (paraphrased) “why do
people use ‘self.some_method’ instead of just ‘some_method’?”.

I knew that I had a lot of redundant 'self’s and a few days ago I got
around to removing them in a script. As Jeremy points out, leaving off
‘self’ in ‘some_method=’ results in the creation of the variable
‘some_method’, as testing showed.

js