Search code examples
rubyoopmethodsinstancesetter

What is the difference between an instance method used to rename an object and a setter method?


If I want to rename my jedi object below, why would I create an instance method named rename that uses the setter method name=? Why not just use the setter method `name=' directly?

Why do this:

     class Skywalker
       attr_accessor :name

       def initialize(name)
         @name = name
       end

       def rename(new_name)
         self.name = new_name
       end
     end

     jedi = Skywalker.new('Anakin')
     puts jedi.name
     jedi.rename('Luke')
     puts jedi.name

When you could just do this:

     class Skywalker
       attr_accessor :name

       def initialize(name)
         @name = name
       end
     end

     jedi = Skywalker.new('Anakin')
     puts jedi.name
     jedi.name = 'Luke'
     puts jedi.name

Both code snippets above do the same thing, so I'm wondering if there is a situation where it would be useful to have the instance method rename in addition to the setter method name=. Because to me it looks like they are redundant.


Solution

  • #rename hides the implementation details. You expose a clean and explicit interface - an object can be renamed, but the caller doesn't have to care how it's done. I would recommend to use attr_reader :name instead of attr_accessor :name to avoid exposing the setter.

    If you expose just #name= you let the caller to change object internals. It may cause the future changes harder (e.g. if you move name to a separate object).