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

  • Thread starter Stefan Salewski
  • Start date
S

Stefan Salewski

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 method `b' for
#<Test:0x7f85f99c02f8 @b=1, @a=0> (NameError)
from test.rb:16

Best regards,

Stefan Salewski
 
T

Tony Arcieri

[Note: parts of this message were removed to make it a legal post.]

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

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 method `b' for
#<Test:0x7f85f99c02f8 @b=1, @a=0> (NameError)
from test.rb:16

Best regards,

Stefan Salewski
 
A

Andrew Wagner

[Note: parts of this message were removed to make it a legal post.]

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.
 
J

Jeremy Bopp

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 :)


-Jeremy
 
J

John Sikora

Jeremy said:
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
 
J

Jeremy Bopp

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.

Thanks go to Dave Thomas, Chad Fowler, Andy Hunt, and their book
"Programming Ruby" -- my introduction to Ruby. :)

-Jeremy
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top