patternrubyCritical
Why use Ruby's attr_accessor, attr_reader and attr_writer?
Viewed 0 times
whyandattr_writeruserubyattr_readerattr_accessor
Problem
Ruby has this handy and convenient way to share instance variables by using keys like
Why would I choose
attr_accessor :var
attr_reader :var
attr_writer :varWhy would I choose
attr_reader or attr_writer if I could simply use attr_accessor? Is there something like performance (which I doubt)? I guess there is a reason, otherwise they wouldn't have made such keys.Solution
You may use the different accessors to communicate your intent to someone reading your code, and make it easier to write classes which will work correctly no matter how their public API is called.
Here, I can see that I may both read and write the age.
Here, I can see that I may only read the age. Imagine that it is set by the constructor of this class and after that remains constant. If there were a mutator (writer) for age and the class were written assuming that age, once set, does not change, then a bug could result from code calling that mutator.
But what is happening behind the scenes?
If you write:
That gets translated into:
If you write:
That gets translated into:
If you write:
That gets translated into:
Knowing that, here's another way to think about it: If you did not have the attr_... helpers, and had to write the accessors yourself, would you write any more accessors than your class needed? For example, if age only needed to be read, would you also write a method allowing it to be written?
class Person
attr_accessor :age
...
endHere, I can see that I may both read and write the age.
class Person
attr_reader :age
...
endHere, I can see that I may only read the age. Imagine that it is set by the constructor of this class and after that remains constant. If there were a mutator (writer) for age and the class were written assuming that age, once set, does not change, then a bug could result from code calling that mutator.
But what is happening behind the scenes?
If you write:
attr_writer :ageThat gets translated into:
def age=(value)
@age = value
endIf you write:
attr_reader :ageThat gets translated into:
def age
@age
endIf you write:
attr_accessor :ageThat gets translated into:
def age=(value)
@age = value
end
def age
@age
endKnowing that, here's another way to think about it: If you did not have the attr_... helpers, and had to write the accessors yourself, would you write any more accessors than your class needed? For example, if age only needed to be read, would you also write a method allowing it to be written?
Code Snippets
class Person
attr_accessor :age
...
endclass Person
attr_reader :age
...
endattr_writer :agedef age=(value)
@age = value
endattr_reader :ageContext
Stack Overflow Q#5046831, score: 790
Revisions (0)
No revisions yet.