想象一下,我们有一些方法
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
但是这个方法不再运行了,如果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
应该返回一个已编译的方法而不是反射对应的
答案 0 :(得分:1)
是的,看起来“反而挂钩”总是“替代”原始方法执行,即使链接条件不成立,差异只是我们是否返回相反链接评估的值或只是零强>
也许这应该改为链接。
作为用例的解决方案,如果条件成立,您可以使用只返回接收者的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)