2012-04-03 6 views
2

私はいくつかのメソッドチェインをしたいと思っています。だから、メソッドがチェーンされているときの検出

class MyClass 

    attr_accessor :handler 

    def do_a 
    puts 'i just did a' 
    self.handler = 'a' 
    self 
    end 

    def do_b_if_a 
    puts 'i just did b' if handler == 'a' 
    end 

end 

次作品:私は、次のコードを持っている

私が仕事をしたい、私はそれが今do_b_if_aができることを意味ハンドラを設定する第1の時間do_a呼び出したときにされてはいけない何
irb > test = MyClass.new 
=> #<MyClass:0x007fa44ced9a70 @handler=nil> 
irb > test.do_a 
'i just did a' 
irb > test.do_a.do_b_if_a 
'i just did a' 
'i just did b' 

いつでも呼び出されます。しかし、do_aで連鎖されているときだけ呼び出すことができます。どうすればいいですか?

答えて

0

私はあなたが状態を追跡していると思います間違った場所。あなたは、たとえば、ActiveRecordののクエリインターフェイスに類似したものとしたほうが良いと思います:

class MyClass 
    attr_accessor :handler 

    def do_a 
    puts 'i just did a' 
    with_handler 'a' 
    end 

    def do_b_if_a 
    puts 'i just did b' if handler == 'a' 
    end 

private 

    def with_handler(h) 
    o = dup 
    o.handler = h 
    o 
    end 

end 

あなたは常にMyClassのインスタンスを持っていますが、その歴史を追跡使い捨てのコピーを持っているこの方法。これはcHao'sのアプローチと似ていますが、MyClass自体を飾ることができるので、追加のデコレータクラスは必要ありません。

1

一般的に、あなたのメソッドが特定の方法で呼び出された場合、気にしたくない(ほとんどの場合、にはが分かります)。そういうわけで、狂気がある。マジック・コール・シーケンスは、デバッグとテストのために非常に役に立ちます。

do_aの代わりにselfを返す代わりに、do_bを定義するデコレータをラップし、デコレータを返します。その時点で、元のMyClassにはdo_bを入力できません。理由はわかりません。しかし、返されたものはdo_aから返すことができます。

(今は、あなたはまだ a = test.do_a、その後 a.do_bのように言うことができますが、あなたは本当にRubyは自分のコードを解析することなく、その周りを取得することはできません。)チャオが言ったように、あなたはメソッド呼び出しに試すべきではありません

0

パターン。しかし、私はまた、これを行うための別の方法を考えることができます。

def do_a 
    puts "i just did a" 
    do_b_if_a(true) 
end 

def do_b_if_a(did_a=false) 
    puts "i just did b" if did_a 
end 

do_a  # prints "i just did a" 
do_b_if_a # does nothing 

確かに、あなたできコールdo_b_if_a(true)、しかし、それはちょうどそれがより柔軟になります。)

+0

問題はまだオブジェクトにアクセスする必要があることです。 –

+0

オブジェクトへのアクセスはどういう意味ですか? – Jwosty

0

はあなたにそこにすべての方法を取得していませんが、あなたはto_aが呼び出されたときに追加されますシングルトン方法としてdo_b_if_aを定義することができます:あなたが取るしたい場合は、Kernel.callerを見て取ることができる

class MyClass 

    def do_a 
    puts 'i just did a' 
    self.tap{|s| def s.do_b_if_a; puts 'i just did b' end} 
    end 

end 

コールスタックに基づく特定のアクション。しかし、あなたが正当な理由がない場合は、別の開発者が顔を殴られるかもしれません。

関連する問題