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

PostcardクラスにインクルードするMailモジュールを定義する演習

さっそくやっていきます。

問題

以下のコード例を実行した時に、
出力例のような文が標準出力へ出力されるように、
コードにincludeされる「Mail」モジュールを定義してください。

 1. class Postcard
 2.   include Mail
 3.   
 4.   def initialize(sender, recipient)
 5.     @sender, @recipient = sender, recipient
 6.   end
 7. end
 8.  
 9. card = Postcard.new("Me", "Friend")
10. card.write("Did you forget my birthsday?")
11. card.send
12. puts "-" * 60
13. sleep(2)
14. puts card

出力例

Tue Mar 22 11:59:16 +0900 2011: Sending a Postcard to Friend.
------------------------------------------------------------
Postcard of Tue Mar 22 11:59:16 +0900 2011:

Dear Friend,

Did you forget my birthsday?

Sincerely,
Me
私の回答・解説

今回はモジュールを作る問題です。
いつも通り作り方が分からないので調べながら進めていきます。

  1. まず始めに出力例を見ると時刻(おそらく現在時刻)が
    表示されています。
    これはTime.nowで取得できるようです。
  2. 次に、出力例にPostcardと表示されている箇所については、
    おそらくクラス名を表示していると思われます。
    これはself.classと書くと取得できます。
  3. あとは、誰から誰に送ったかという情報が
    Postcardクラスのinitializeメソッドに渡されているので、
    これをどうにかしてMailモジュールで使えるようにしないといけません。
    これについて調べたところ、
    クラスのインスタンス変数はモジュールでも使えるそうなので、
    そのまま使っちゃいます。
    以上を踏まえ完成したソースがこちら

模範解答(モジュール部分のみ)はこちら

 1. module Mail
 2.   attr_reader :sender, :recipient, :text, :date
 3.  
 4.   def send
 5.     puts "#{@date = Time.now}: Sending a #{self.class} to #{self.recipient}."
 6.   end
 7.  
 8.   def write(text)
 9.     @text = text
10.   end
11.  
12.   def to_s
13.     "#{self.class} of #{@date}:\n\nDear #{@recipient},\n\n#{@text}\n\nSincerely,\n#{@sender}"
14.   end
15. end

今回は程々に一緒ですね。
ただ、私はattr_readerを書いていません。
これは、書くのがマナーというか作法なんですかね。
あと、#{@date = Time.now}みたいに一発で書けるんですね。

次回は「各Planetクラスのインスタンスにlifeメソッドを定義する演習」をやります。