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
> 

Reply via email to