2016-10-23 13 views
1

でメソッドをスキップし、我々はあなたがMyClass new method: 1を行う際に、いくつかの方法は条件付きでメタリンク

MyClass>>#method: arg 

    Transcript crShow: 'executed' 

だから転写物が「実行」ラインで満たされている必要があり想像してみてください。 argは私が条件と代わりメタリンクをインストールしようとした0の場合

は、今私は、このメソッドをスキップする:

link := MetaLink new 
    condition: [ :arguments | 
     arguments first = 0 ] 
    arguments: #(arguments); 
    control: #instead. 

(MyClass >> #method:) ast link: link 

しかし、その後方法はもう実行されませんし、私がしたいですargが0

でない場合、私はまた、このようにメタオブジェクトに条件を行うことを試みたことを実行します。

link := MetaLink new 
    metaObject: [ :ast :arguments :receiver | 
     arguments first = 0 
     ifFalse: [ 
     ast compiledMethod 
      valueWithReceiver: receiver 
      arguments: arguments ] ]; 
    selector: #value:value:value:; 
    arguments: #(node arguments receiver); 
    control: #instead. 

(MyClass >> #method:) ast link: link 

しかし、この場合、ast compiledMethodはコンパイルされたメソッドを返すべきだと思うが、メタリンクが何度も繰り返し呼び出されるので、無限の再帰で終わる。

答えて

1

はい、それは "代わりにフック"元のメソッドの代わりに常に "代わりに"実行されますが、リンク条件が成立していない場合でも、代わりに代わりのリンク評価の値を返すか、ちょうどnilの値を返します。

リンクの代わりにこれを変更する必要があるかもしれません。

| ml | 
ml := MetaLink new. 
ml control: #before. 
ml condition:[:args | args first = 0] arguments:#(arguments). 
ml selector:#value:. 
ml metaObject:[:context | context return]. 
ml arguments:{#context}. 

(MyObject>>#method:) ast link:ml. 

#contextはthisContextのrefication(RFThisContextReification)

するためのキーである:

あなたのユースケースのためのソリューションとして、あなたは条件が成立した場合にだけ受信を返すリンクする前に使用することができます