I was looking at this and ran into some very odd behavior: imagine we have some method:
``` Object subclass: #MyClass. MyClass compile: 'method: arg Transcript crShow: ''executed '', arg asString'. ``` and a simple metalink ``` link := MetaLink new metaObject: Halt; selector: #now; control: #instead. (MyClass >> #method:) ast link: link. ``` Now I can do the following to execute the code: ``` c := MyClass new. (MyClass>>#method:) valueWithReceiver: c arguments: #(1). (MyClass>>#method:) reflectiveMethod valueWithReceiver: c arguments: #(1). (MyClass>>#method:) compiledMethod valueWithReceiver: c arguments: #(1). MyClass rFwithArgs: #(1) executeMethod: (MyClass>>#method:) compiledMethod. ``` All of the statements above will call the method WITHOUT triggering the metalink, which is odd. Now what's even stranger, if I instead do this ``` c := MyClass new. c method: 1. (MyClass>>#method:) valueWithReceiver: c arguments: #(1). (MyClass>>#method:) reflectiveMethod valueWithReceiver: c arguments: #(1). (MyClass>>#method:) compiledMethod valueWithReceiver: c arguments: #(1). MyClass rFwithArgs: #(1) executeMethod: (MyClass>>#method:) compiledMethod. ``` Then ALL the statements (starting with `c method: 1`) will be suddenly halting (triggering the metalinks). So my questions are: 1) why in the first case the following two methods didn't trigger the metalink? (MyClass>>#method:) valueWithReceiver: c arguments: #(1). (MyClass>>#method:) reflectiveMethod valueWithReceiver: c arguments: #(1). 2) why in the second case these two methods did trigger the metalink? (MyClass>>#method:) compiledMethod valueWithReceiver: c arguments: #(1). MyClass rFwithArgs: #(1) executeMethod: (MyClass>>#method:) compiledMethod. #rFwithArgs:executeMethod: even has comment "This method is used by reflectivity internally. All meta-links are ignored". 3) why the class of (MyClass>>#method:) changed after calling `method:`? ``` (MyClass >> #method:) ast link: link. c := MyClass new. (MyClass>>#method:) class. "ReflectiveMethod" (MyClass>>#method:) valueWithReceiver: c arguments: #(1). (MyClass>>#method:) class. "ReflectiveMethod" c method: 1. (MyClass>>#method:) class. "CompiledMethod" ``` 4) (unrelated to the above) I tried calling `link disable` from within the #metaObject, but it was ignored, but maybe I don't understand its purpose. Thanks, Peter On Sun, Oct 23, 2016 at 09:21:59AM +0200, Yuriy Tymchuk wrote: > I’ve also described the question with examples on SO: > https://stackoverflow.com/questions/40200546/conditionally-skip-a-method-with-matalinks > > > On 22 Oct 2016, at 23:13, Yuriy Tymchuk <yuriy.tymc...@me.com> wrote: > > > > Hi. > > > > Imagine I have method a: and I want to skip the execution (return self or > > nil or whatever) when a: is evaluated with parameter 0. I have tried to add > > a meta link which will run instead of the method with a condition, but the > > condition did not work… I have tried to implement the metallic method to do > > nothing if the arg is 0 otherwise to perform the method, but I end up with > > an infinite loop… > > > > Did anybody do something like that already? Any suggestions? > > > > Uko >