リーダーとライター
CoddyのRubyジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 7/57。
すべてのインスタンス変数に対してリーダーメソッドを書くのは繰り返し作業です。クラス本体内の attr_reader :title は、@title を返す title メソッドを生成します。1行に複数の名前を指定できます。
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.pages出力:
Dune
412attr_writer :title は、引数を @title に格納するメソッド title= というセッターを生成します。Rubyでは代入構文 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.title出力:
Dune Messiahattr_accessor は読み取り用とセッターの両方を生成します。両方が用意されているため、player.score += 5 は 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}"出力:
Ada L.: 8できるだけ公開するものを少なくしましょう。外部のコードから読み取れても変更はできない値には attr_reader を使い、外部から値を変更することが設計の一部である場合にのみ writer を追加します。reader 専用の属性に代入すると 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.title出力:
undefined method `title=' for an instance of Book
Duneチャレンジ
簡単Bookクラスを完成させてください。外部のコードからはtitle、author、pagesを読み取ることができ、0から始まるpages_readは読み取りと変更ができます。progressは、パーセンテージを切り捨ててDune: 120/412 (29%)を返します。
提供されたコードは、入力の最初の3行(タイトル、著者、ページ数)から本を作成します。その後の各行は、読者が読み終えたページ数であり、コードはそれぞれをbook.pages_read += nで加算します。最後に、Dune by Frank Herbertと進捗状況を出力します。
コードはbook.rbに記述してください。main.rbには提供された入出力コードが含まれており、編集できません。
自分で試してみよう
require_relative 'book'
# 提供された入出力コード: そのままにしておく
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
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
自分で練習してみよう: Rubyオンラインコンパイラ