I am currently studying a bit of Smalltalk.
Is there a way you can store a function or method inside a variable?
For example, in Python one could say:
x = someobject.method
x() # calling it
Is this possible in Smalltalk? What about passing something.method
itself as an argument to another method?
You can get a method object, by asking the class object for a method with a given name. Below >>
is a message send to the class Object
with the method name as a parameter.
Object >> #asString
This returns an instance of type CompiledMethod
. This is an object representing a method. Like any object you can store it inside a variable.
copyMethod := Object>>#asString.
For example, if you open in Pharo a Playground and inspect the code above you get:
You can then execute the method using the message #valueWithReceiver:arguments:
. This needs as a parameter the receiver (self/this) and possible arguments.
result := copyMethod
valueWithReceiver: Object new arguments: #().
However, this is a low level way to execute a method.
I'd say more common is to the directly execute a method with a given name on an object. That can be done using perform:
or perform:withArguments:
. You can send this to the object with the method name as argument
receiver := Object new.
receiver perform: #asString.
The code above executes the method named asString
on the receiver object. This is often used to pass the names of methods that we need to execute. The difference is that instances of CompiledMethod
are immutable. If you change the code of that method a new instance is created and you can end up executing an older version of the method.