0

In a lesson from codeschool, the code in the top-left block is demonstrated to be incorrect.

"Of course it is", I say to myself. I've learned it should be @name = name. What's the new problem? Why is "self" necessary here instead? See my working code below:

enter image description here

class UserList
    attr_accessor :name
    def initialize(name)
        @name = name
    end
end

list = UserList.new('celebrities')
list.name
the Tin Man
  • 158,662
  • 42
  • 215
  • 303
dwilbank
  • 2,470
  • 2
  • 26
  • 37
  • currently perusing http://stackoverflow.com/questions/1693243/instance-variable-self-vs?rq=1 – dwilbank Oct 09 '13 at 00:53
  • Just to elaborate a little on the answers below, here the method `name=()`, which is generated by `attr_accessor`, must have a receiver to which the method is applied. `self.name=` specifies the receiver to be `self`, which here equals an instance of the class `UserList`. If you did not specify a receiver (just `name=`), Ruby assumes the receiver is `self`, so here it's optional. Note that there are other situations where the use of `self` is not optional. – Cary Swoveland Oct 09 '13 at 02:22

3 Answers3

1

self is not necessary here. What you are doing is equivalent. Either way is fine.

ThomasW
  • 16,981
  • 4
  • 79
  • 106
  • 2
    In this specific case it is equivalent but that's only because the `name=` method is being defined by `attr_accessor`, if you had a `name=` method that actually did something interesting then `@name = 'name'` and `self.name = 'name'` would not be equivalent. – mu is too short Oct 09 '13 at 00:55
  • ah... so codeschool should have shown me that special circumstance... maybe it's in an upcoming lesson – dwilbank Oct 09 '13 at 00:57
  • @dwilbank: I hope so, that example is pretty shallow and misleading (unless there is a bit more meat to the notes that I can't see). There is a bit of possible ambiguity in `a = b`, is that assigning `b` to a local variable `a` or is it calling the `a=` method on `self`? The ambiguity is resolved to be the "local variable `a`" case because otherwise there'd be no sane way to create a local variable (unless there was a keyword (`my`, `var`, ...) for that); if you want to call the `a=` mutator method then you have to resolve the ambiguity by hand and say `self.a =`. – mu is too short Oct 09 '13 at 01:02
0

self.name = calls the name= method which sets the instance variable @name. What you are doing is equivalent.

Borodin
  • 126,100
  • 9
  • 70
  • 144
tomciopp
  • 2,602
  • 2
  • 31
  • 60
0

Codeschool is introducing attr_accessor here. And you are right the lines

@name     = name
self.name = name

are equivalent.

But on the one hand why choose attr_accessor (and not attr_reader) and then write @name=? One part of the learning is that attr_accessor creates a setter method. Using attr_accessor with @name= is kind of useless.

And on the other hand they wanted to point out an other important detail: Even if attr_accessor creates a method def name=(name), non of this will work:

name = name
name = 'Bart'

Because it would never change the underlying @name variable nor even touch the method created with attr_accessor. It would change the local variable name.

And this is an important learning. Know the difference between name= and self.name=.

spickermann
  • 100,941
  • 9
  • 101
  • 131