Readers and Writers
Part of the Object Oriented Programming section of Coddy's Ruby journey. Lesson 7 of 57.
Writing a reader method for every instance variable is repetitive. attr_reader :title in the class body generates the method title, which returns @title. One line can list several names:
class Book
attr_reader :title, :pages
def initialize(title, pages)
@title = title
@pages = pages
end
end
book = Book.new("Dune", 412)
puts book.title
puts book.pagesOutput:
Dune
412attr_writer :title generates a setter, the method title=, which stores its argument in @title. Ruby lets you call it with assignment syntax, book.title = "Emma":
class Book
attr_reader :title
attr_writer :title
def initialize(title)
@title = title
end
end
book = Book.new("Dune")
book.title = "Dune Messiah"
puts book.titleOutput:
Dune Messiahattr_accessor generates both the reader and the setter. With both in place, shorthand such as += works too, because player.score += 5 means player.score = player.score + 5:
class Player
attr_accessor :name, :score
def initialize(name)
@name = name
@score = 0
end
end
ada = Player.new("Ada")
ada.score += 5
ada.score += 3
ada.name = "Ada L."
puts "#{ada.name}: #{ada.score}"Output:
Ada L.: 8Expose as little as you can. Use attr_reader for values that outside code may read but not change, and add a writer only where changing the value from outside is part of the design. Assigning to a reader-only attribute raises NoMethodError:
class Book
attr_reader :title
def initialize(title)
@title = title
end
end
book = Book.new("Dune")
begin
book.title = "Emma"
rescue NoMethodError => e
puts e.message
end
puts book.titleOutput:
undefined method `title=' for an instance of Book
DuneChallenge
EasyComplete the class Book. Outside code can read title, author and pages, and it can read and change pages_read, which starts at 0. progress returns Dune: 120/412 (29%), with the percentage rounded down.
The supplied code creates a book from the first three input lines (title, author, pages). Every following line is a number of pages the reader got through; the code adds each with book.pages_read += n. Finally it prints Dune by Frank Herbert and the progress.
Your code goes in book.rb. main.rb holds the supplied input/output code and cannot be edited.
Try it yourself
require_relative 'book'
# Supplied input/output code: keep it as it is
input = []
while (line = gets)
input << line.chomp
end
book = Book.new(input[0], input[1], input[2].to_i)
input.drop(3).each { |n| book.pages_read += n.to_i }
puts "#{book.title} by #{book.author}"
puts book.progress
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Object Oriented Programming
1Classes and Objects
Working With FilesDefining ClassesInstance VariablesMethods and selfto_s and inspectRecap - Library Card7Polymorphism and Duck Typing
PolymorphismDuck TypingAbstract Methodscase and ClassesRecap - Payment Methods2Accessors and Self
Readers and WritersCustom Settersself in MethodsIdentity and EqualityRecap - Contact List8Special Methods
Equality and hashOperator MethodsIndexing and AppendingCustom CollectionsRecap - Fractions11Project: Library Management
Books and MembersBorrowing Books3Class Methods and Variables
Class MethodsClass Instance VariablesConstantsFactory MethodsRecap - Coupon CodesPractice on your own: Online Ruby compiler