dimanche 23 octobre 2016

Conditionally skip a method with Matalinks

Imagine we have some method

MyClass>>#method: arg

    Transcript crShow: 'executed'

So when you do MyClass new method: 1 the transcript is filled with "executed" lines.

Now I want to skip this method is arg is 0. I've tried to install an instead metalink with a condition:

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

(MyClass >> #method:) ast link: link

But then the method does not run anymore and I want to run it if the arg is not 0.

I've also tried to do the condition in the metaobject in this way:

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

But in this case you end up in a infinite recursion, as the metalink is called over and over again although I thought that ast compiledMethod should return a compiled method and not the reflective counterpart





Aucun commentaire:

Enregistrer un commentaire