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
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.
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.:
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.
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
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.