「Rubyがミニツク」の演習問題を解く vol5

BookクラスとLibraryクラスを定義する演習

前回でミニツクの入門コースの演習問題が終わったので、
今回から演習コースに入っていく。

難易度は上がっていますが、
ネットや調べたり、書籍を読んでもOKなので
まぁなんとか(動くレベルには)なると思います。

では、やっていきます。

問題

以下のコード例に利用されている
BookクラスとLibraryクラスを定義してください。
なお、コード例を実行した上で、
以下の出力例の文が標準出力へ出力されるように
定義しておいてください。

私の回答・解説

まずは、コード例の確認から始めます。
1行目のmy_library = Library.new

  1. Library.newでLibraryオブジェクトを生成している。
  2. Library.newに引数の指定はない。

以上の事から、Libraryクラスにinitializeメソッドは不要ですね。

次に2, 3行目はBookクラスのオブジェクト生成ですが、

  1. newに引数を渡している。
  2. 引数に引数名のようなものを指定している。
  3. 第3引数にmy_libraryを渡している。

以上の事から、Bookクラスにinitializeメソッドが必要そうです。
ただ、引数の指定の仕方がよく分かりません。
こんな時は、潔くネットで調べます。
どうやら「キーワード引数を受け取るメソッド」を呼び出す時の書き方らしいです。
メソッドを書く時は引数名の末尾に「:」を付けます。

最後4行目は、puts my_libraryとしているだけですが、

  1. 出力例を見るとBookの情報が出力されている。

なので、LibraryクラスにBookの情報を保持する必要がありそうです。

以上を踏まえて、考えたソースコードがこちら。 Libraryクラスにinitializeメソッドは不要と思ってたのですが、
bookクラスを保持する配列を初期化するために使いました。
LibraryクラスにBookクラスを追加するためにadd_bookメソッドを作りました。
自分的には満足いってます。

模範解答はこちら

 1. class Library
 2.   def initialize
 3.     @books = []
 4.   end
 5.  
 6.   def <<(book)
 7.     @books << book
 8.   end
 9.  
10.   def to_s
11.     puts "Library contents:"
12.     @books.join("\n")
13.   end
14. end
15.  
16. class Book
17.   attr_accessor :author, :title
18.   def initialize(args)
19.     @author = args[:author]
20.     @title  = args[:title]
21.     args[:library] << self
22.   end
23.  
24.   def to_s
25.     "Title: " + @title + ", Author: " + @author
26.   end
27. end

チーン。
色々ミスってますね。
Arrayクラスには<<メソッド(=Pushメソッド)というのがあるみたいです。
入門コースのArrayクラスのレッスンにちゃんと書いてありました。 Book.newメソッドの定義の仕方も間違ってました。
ハッシュを渡すことで引数1つで実現してるんですね。 ネットで調べたキーワード引数でもいいのかな。

今回は勉強になりました。

次回は「clever_printメソッドを定義する演習」をやります。