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

Discussion in 'Ruby' started by Stefan Salewski, Oct 6, 2010.

  1. 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
     
    Stefan Salewski, Oct 6, 2010
    #1
    1. Advertising

  2. Stefan Salewski

    Tony Arcieri Guest

    [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

    On Wed, Oct 6, 2010 at 4:11 PM, Stefan Salewski <> wrote:

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



    --
    Tony Arcieri
    Medioh! A Kudelski Brand
     
    Tony Arcieri, Oct 6, 2010
    #2
    1. Advertising

  3. [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.

    On Wed, Oct 6, 2010 at 6:11 PM, Stefan Salewski <> wrote:

    > 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
    >
    >
    >
    >
     
    Andrew Wagner, Oct 6, 2010
    #3
  4. Stefan Salewski

    Jeremy Bopp Guest

    On 10/6/2010 5:42 PM, Andrew Wagner 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 :)


    -Jeremy
     
    Jeremy Bopp, Oct 6, 2010
    #4
  5. Stefan Salewski

    John Sikora Guest

    Jeremy Bopp 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

    --
    Posted via http://www.ruby-forum.com/.
     
    John Sikora, Oct 7, 2010
    #5
  6. Stefan Salewski

    Jeremy Bopp Guest

    On 10/06/2010 10:17 PM, John Sikora wrote:
    > Jeremy Bopp 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.


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

    -Jeremy
     
    Jeremy Bopp, Oct 7, 2010
    #6
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Robert Brown
    Replies:
    2
    Views:
    423
    Kevin Spencer
    Jul 3, 2003
  2. Peter Blum
    Replies:
    0
    Views:
    1,136
    Peter Blum
    Feb 25, 2004
  3. =?Utf-8?B?cG11ZA==?=
    Replies:
    8
    Views:
    815
    =?Utf-8?B?cG11ZA==?=
    Feb 11, 2005
  4. flack
    Replies:
    15
    Views:
    6,862
    Gordon Beaton
    Mar 31, 2006
  5. Fabio Pliger

    check instace already running...

    Fabio Pliger, Apr 9, 2005, in forum: Python
    Replies:
    3
    Views:
    450
    Fabio Pliger
    Apr 10, 2005
Loading...

Share This Page