2

As far as I understand CompiledMethod is a class holding the compiled form of a method. An instance of this class is created each time a method is compiled. This instance is saved in the class to which the method belongs.

My question is if I have a the name of the method, how can I get that instance that holds the compile form of a method in order to run that method with valueWithReceiver: ?

is it by using compiledMethodAt: selector ?

Ohad
  • 1,563
  • 2
  • 20
  • 44

3 Answers3

3

I think that we need more context here.

Because using the reflection mechanisms you can even do something like:

CompiledMethod allInstances select: [ :m | m selector = #asString ]

And this will give you all methods with a selector asString. But this action is very strange.

You can also use #detect: instead of #select: to find a single method.

If you need to evaluate all found methods, you can use:

CompiledMethod allInstances
    select: [ :m | m selector = #asString ]
    thenDo: [ :m | m valueWithReceiver: aReceiver ]

Also if you are interested in a methods for one hierarchy, you can do

YourClass withAllSubclassesDo: [ :class |
    class
        compiledMethodAt: #selector
        ifPresent: [ :method | method valueWithReceiver: aReceiver ]
        ifAbsent:  [ "do nothing" ]
Uko
  • 13,134
  • 6
  • 58
  • 106
  • hey Uko..I actually need to get all the methods with the same name (in the inheritance chain), so I was trying your way : CompiledMethod allInstances select: [ :m | m selector = #asString ].. but it doesn't work... is m the compiled method? can I run each m inside this block? – Ohad Dec 12 '14 at 11:05
  • @Shiran I've added explanation how to evaluate all found methods and an option for hierarchy – Uko Dec 12 '14 at 13:38
2

If you are not sure, what you get as answer of a message send, you can always ask for the results class. Print:

(Behavior compiledMethodAt: #compiledMethodAt:) class

In this case it is CompiledMethod - exactly, what you were looking for. And yes, you can use a compiled method with valueWithReceiver:.

MartinW
  • 4,966
  • 2
  • 24
  • 60
  • It works :-) I have used compiledMethodAt to get the instance of the compiled method ... thanks – Ohad Dec 11 '14 at 17:46
0

You can make the virtual machine look up the method for you, and run it, with an expression like:

object perform: selector

The virtual machine will look up the method associated with selector in object's class, and run it with object as the receiver. There are similar forms of this message for passing parameters.

  • so by doing this it will run all the methods associated with selector? – Ohad Dec 12 '14 at 11:14
  • I need to run the methods I have override and the new method as well – Ohad Dec 12 '14 at 11:15
  • It will run the single method that the virtual machine's lookup procedure finds. Lookup starts with the class of the receiver, and proceeds through the superclasses of that class, through class Object. If no method is found, it will signal the MessageNotUnderstood exception. To run overridden methods, use the valueWithReceiver: technique suggested above. – Craig Latta Dec 12 '14 at 12:40