2016-10-10 3 views
1

私はプログラミングRubyの式の宣言を読んでいます。<<なぜメソッドがselfを返すのがメソッド連鎖に役立つのか?

class ScoreKeeper 
    def initialize 
    @total_score = @count = 0 
    end 
    def <<(score) 
    @total_score += score 
    @count += 1 
    self 
    end 
    def average 
    fail "No scores" if @count.zero? 
    Float(@total_score)/@count 
    end 
end 

scores = ScoreKeeper.new 
scores << 10 << 20 << 40 
puts "Average = #{scores.average}" 

これは

Average = 23.333333333333332 

を生産する本は、このコード< <方法を明示的 戻っ自己で微妙があること

注意をexpains。スコア オブジェクトを返します< <への各呼び出しは、あなたは、新しいスコアを渡し、再び< <を呼び出すことができますのでこの方法はラインに スコア< < 40をチェーンできるようにこれを行います。

私はまだ方法連鎖を許可する理由を理解していません。
誰かが助けることができますか?

+0

あなたは 'デフ<<' 'からそのself'を削除しようとしたことがありますか? – Stefan

答えて

3

あなたはscores << 10、オブジェクト、つまり、レシーバを返しますので、あなたがこの

scores = ScoreKeeper.new 
scores << 10 << 20 

作品

undefined method << for Fixnum 

を言ってエラーに終わるでしょうscores << 2 << 1を書かれた、@count += 1selfを返さなかったであろう場合それはメソッド<<を定義しました。例えばscoresです。したがって、メソッド呼び出しを連鎖させることができます。

selfを指定しないと、<<メソッドの戻り値が数値になるため、メソッド呼び出しを連鎖させることができません。

実際に、それはさらに悪いです:<< is defined for Integers、あなたは が取得することはできませんのでイェルクWミッタークによってコメントを1としてEDIT

(あなたはRubyの2.4.xの上にあると仮定した場合)エラーではなく、明らかに間違った結果になります。 (以上 正確に、後でエラーになります、 非既存Integer#averageメソッドを呼び出すこと。しようとしたとき)

+0

"となり、スコアはScoreKeeperのインスタンスになります。なぜなら、self"を返すからです。これらの2つの事実には関係がありません。 :) –

+0

'score'は' ScoreKeeper'だけでなく、 'Score << 10'も' ScoreKeeper 'です。これが連鎖の前提条件です。あなたはこれを知っているのを知っちょうどここで言葉を改善したいです:) –

+0

@SergioTulentsevありがとう、この部分を改めて:) –