有条件地跳过带有metalink的方法



假设我们有一个方法

MyClass>>#method: arg
    Transcript crShow: 'executed'

所以当你做MyClass new method: 1时,转录本被"执行"行填充。

现在我想跳过这个方法,如果arg是0。我试图安装一个而不是 metalink,条件是:

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

但是这个方法不会再运行了我想在参数不为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应该返回一个编译的方法,而不是反射的对应

是的,看起来"代替钩子"总是执行"代替"原始方法,即使链接条件不成立,区别只是我们是否返回代替链接评估的值或只是nil

也许这应该改为链接。

作为您的用例的解决方案,您可以使用before链接,如果条件成立,它只返回接收者:

| 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配置(RFThisContextReification)的关键

相关内容

  • 没有找到相关文章

最新更新