If you can separate the message argument from the message itself, you can "send" the message:
obj := 3. msg := '+'. arg := 5. result := obj perform: msg asSymbol with: arg.
Otherwise, you will have to use a compiler that translates the string into compiled code and executes it:
obj := 3. msg := 'self + 5'. result := Compiler evaluate: msg for: obj logged: false.
A common method to avoid recompilation is to compile a block that can be evaluated more efficiently:
obj := 3. msg := '[:x | x + 5]'. block := Compiler evaluate: msg. result := block value: obj.
Btw, the code above (and below) for Squeak, other Smalltalks may have a different way of accessing the compiler.
There is an even more hacker way that allows you to access a variable directly from a string. This is by executing the compiled code in "thisContext" (in this case, you need to declare temporary vars even in the workspace):
| obj msg result | obj := 3. msg := 'obj + 5'. result := Compiler new evaluate: msg in: thisContext to: nil.
However, I would not recommend this latest technique. Execution is usually safer than using a compiler. However, this can be used to implement some serious metafiles. For instance:.
| obj | obj := 3. 'The result is {obj + 5}.' expand
The implementation of the expand method remains for the curious reader;)
source share