Ruby Attribute Patterns
The beginner course used attr_reader, attr_writer and attr_accessor to write simple access methods. This lesson sets those lines beside hand-written versions and adds checks and computed readers.
attr lines beside hand-written twins
Dog uses attr_accessor for its name. Cat writes the same reader and writer by hand, and both animals end with a new name.
class Dog
attr_accessor :name
def initialize(name)
@name = name
end
end
class Cat
def initialize(name)
@name = name
end
def name
@name
end
def name=(value)
@name = value
end
end
dog = Dog.new("Rex")
cat = Cat.new("Milo")
dog.name = "Max"
cat.name = "Ruby"
puts dog.name
puts cat.nameA writer that checks its value
The hand-written price writer stores zero when the new price is negative. A fair price passes through unchanged.
class Product
attr_reader :price
def initialize(price)
@price = price
end
def price=(value)
if value < 0
@price = 0
else
@price = value
end
end
end
item = Product.new(10)
puts item.price
item.price = -5
puts item.price
item.price = 7
puts item.priceOne line for two names
A single attr_accessor line names title and pages together. Both values can be read and set from outside.
class Book
attr_accessor :title, :pages
def initialize(title, pages)
@title = title
@pages = pages
end
end
book = Book.new("Poems", 80)
puts book.title
puts book.pages
book.pages = 96
puts book.pagesA reader that computes
area stores nothing and multiplies the stored sides on each call. Changing the width changes the next area at once.
class Rectangle
attr_writer :width
def initialize(width, height)
@width = width
@height = height
end
def area
@width * @height
end
end
shape = Rectangle.new(4, 5)
puts shape.area
shape.width = 6
puts shape.areaExample
class Ticket
attr_reader :price
attr_accessor :seat
def initialize(seat, price)
@seat = seat
@price = price
end
def price=(value)
if value < 0
@price = 0
else
@price = value
end
end
def summary
"#{@seat} costs #{@price}"
end
end
ticket = Ticket.new("A1", 20)
puts ticket.summary
ticket.price = -3
puts ticket.price
ticket.seat = "B2"
puts ticket.summaryKey points
- A hand-written reader returns the stored value, just like attr_reader.
- A hand-written writer stores a new value, just like attr_writer.
- A writer written by hand can check its value before storing it.
- One attr_accessor line can name two values at once.
- A reader can compute its answer from stored values on every call.
In this example, seat uses attr_accessor while price pairs a plain reader with a checking writer. Setting a negative price stores zero instead. summary computes its line from the current seat and price on every call.
Note
The attr lines and the hand-written methods give the same results when the jobs are plain.
Try it Yourself
Edit the code, then press Run.
Running is simulated
Exercise
In the checking writer from this lesson, what price is stored after item.price = -5?