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-wit...
On 22 Oct 2016, at 23:13, Yuriy Tymchuk <yuriy.tymchuk@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