1

If I have a class like this:

class Person

  def initialize(options={})
    self.name = options[:name]
  end

  def name=(name)
    @name = name
  end

end

... then the 'name=' method gets called and I get what I expect. But if I alter the example slightly to drop the 'self' from the call to 'name=' then the method is never called:

class Person

  def initialize(options={})
    name = options[:name]
  end

  def name=(name)
    @name = name
  end

end

Why is this? Why must 'self' be there? I was under the impression that the implicit 'self' would be set as expected in the 'initialize' constructor and therefor would behave as the first example.

dreadwail
  • 15,098
  • 21
  • 65
  • 96
  • BTW, self is required to call an accessor not just in the constructor but in every other instance method too – Thong Kuah Jun 29 '13 at 05:00
  • This is certainly *related* to the question it is marked a duplicate of, but by the time someone knows the question asked in the marked duplicate, this question is already answered. This question is about the appearance of needing `self.` for all instance methods called in `initialize`. The fact that `self.` is needed for accessors is the *answer* to this question. – Darshan Rivka Whittle Jun 29 '13 at 09:24

2 Answers2

7

Ruby doesn't know if you want to make a local variable named "name" or use the member variable.

self.name tells it you want to use the member variable.

There isn't any syntax for saying you want to create a local variable, so that has to be the default.

(Also, member variables aren't real, but you know what I mean)

xaxxon
  • 19,189
  • 5
  • 50
  • 80
-1

Why is 'self' required to call a Ruby method from within its constructor?

In general, it's not:

class Person
  def initialize(options={})
    set_name(options[:name]) # Calls `set_name` method; no `self.` required
  end

  def set_name(name)
    @name = name
  end
end

The need for self. in your code has nothing to do with being in the constructor: you can call any normal instance method from within initialize or elsewhere in the class without using self..

What's going on is that you're trying to call a setter method (an instance method whose name ends with =, e.g. name=), which are handled as a special case in Ruby.

According to The Ruby Programming Language:

The rule is that assignment expressions will only invoke a setter method when invoked through an object. If you want to use a setter from within the class that defines it, invoke it explicitly through self.

So again, it's not that Ruby doesn't know what self refers to during execution of the constructor -- it does -- it's that in this case you're trying to call a setter, which requires invocation through an object.

In your code, name = options[:name] creates and sets a local variable called name.

Darshan Rivka Whittle
  • 32,989
  • 7
  • 91
  • 109