8

There's a convention to reference an object's attributes over its instance variables, where possible. Practical Object-Oriented Design in Ruby says:

Always wrap instance variables in accessor methods instead of directly referring to variables...

This is shown with an example, which I've paraphrased:

class Gear
  attr_reader :chainring, :cog
  ...
  def ratio
    # this is bad
    # @chainring / @cog.to_f
    # this is good
    chainring / cog.to_f
end

The most common way I see to create a new object with an instance variable is this:

class Book
  attr_accessor :title
  def initialize(title)
    @title = title
  end
end

@title= directly accesses the instance variable title. Assuming we are following the the 'attribute over instance variable' convention, is it more appropriate to use self.title=, which would tell the object to send itself the message title=, thereby using the attribute write method, over the instance variable directly?

class Book
  attr_accessor :title
  def initialize(title)
    self.title = title
  end
end

The book talks about 'attribute over instance variable' with reference to reading an instance variable, but doesn't it also apply to writing?

Community
  • 1
  • 1
ben
  • 29,229
  • 42
  • 124
  • 179
  • In some case `self.feature=` is more preferably than `@feature=`, generally in that case when assignment to `self.` shell do more actiona then just assignment. In second, here: https://github.com/3aHyga/ruby-style-guide you can see that good style `self.feature=` is encontered only once, when the complex assignment (it means that not just assisnment to a instance variable) is occurred. In case of read always used construction like `feature == "value"` – Малъ Скрылевъ Jan 10 '14 at 17:15

2 Answers2

10

The book talks about 'attribute over instance variable' with reference to reading an instance variable, but doesn't it also apply to writing?

Yes, it also applies to writing. However, the initialize method is special because it is responsible for setting up the object. When you use a setter method, you do that because the setter might be doing some extra work (e.g. attribute-setters in Rails). In an initializer, you usually don't want to have any side effects, so you access instance variables directly.

Nick Urban
  • 3,568
  • 2
  • 22
  • 36
phoet
  • 18,688
  • 4
  • 46
  • 74
0

At first, in some case self.feature= is more preferably than @feature=, generally in that case, when assignment to feature property shell do more actions, then just assignment. For example, in a database access methods.

At second, in the good ruby style guide you can see that good style self.feature= is encontered only once, when the complex assignment is occurred. It means that not just assisnment to a instance variable. In case of read, construction like feature == "value" is always used.

Малъ Скрылевъ
  • 16,187
  • 5
  • 56
  • 69