0

I am familiar with the conventional way of using attr_accessors within the initialize method:

class Dog
    attr_accessor :name

    def initialize(name)
        @name = name
    end
end

dog = Dog.new("Denver")
p dog.name

=> "Denver"

I was playing around with custom writers and readers. I was suprised to realize the following:

  • Within instance methods: you can call upon a reader method without explicitly specifying self because self is implicit.
  • Within instance methods: you MUST explicitly call self to call upon a writer method. self IS NOT implicit for attr_writers

Example 1 to show that self is implicit when calling attr_reader methods within instance methods:

class Dog
    def name
        @name
    end

    def name=(val)
        @name = val
    end

    def initialize(name)
        @name = name
    end

    def call_name
        # no need to say: p self.name
        p name
    end
end

dog = Dog.new("Denver")
dog.call_name

=> "Denver"

Example 2 to show that self IS NOT implicit when calling upon attr_writers within instance methods. In other words: the instance variable is not getting set because I did not prepend the writer method below with self:

class Dog
    def name
        @name
    end

    def name=(val)
        @name = val
    end

    def initialize(name_val)
        # works as expected with: self.name = name_val
        name = name_val 
    end

    def change_name
        # works as expected with: self.name = "foo"
        name = "foo"
    end
end

dog = Dog.new("Denver")
p dog.name

dog.change_name
p dog.name

=> nil
=> nil

Question: why isn't self implicit within instance methods when calling attr_writers? Why do I have to explicitly specify self for attr_writers within instance methods?

Neil
  • 4,578
  • 14
  • 70
  • 155

1 Answers1

0

Question: why isn't self implicit within instance methods for attr_writers?

Because defining a local variable takes precedence.

So here:

name = "foo"

you do not write an attribute, but defining a local variable name.

Andrey Deineko
  • 51,333
  • 10
  • 112
  • 145