オブジェクトと、それに送信したいメッセージを含む文字列があります。
たとえば、整数オブジェクトに送信したい文字列'+5'。
ワークスペースにある場合は、「obj + 5」と書くだけですが、文字列を事前に知らなくても、実行時に実行する必要があります...
メッセージの引数をメッセージ自体から分離できる場合は、メッセージ送信を「実行」できます。
obj := 3.
msg := '+'.
arg := 5.
result := obj perform: msg asSymbol with: arg.
それ以外の場合は、コンパイラを使用する必要があります。コンパイラは、文字列をコンパイル済みコードに変換して実行します。
obj := 3.
msg := 'self + 5'.
result := Compiler evaluate: msg for: obj logged: false.
コンパイルの繰り返しを回避するための一般的な手法は、ブロックをコンパイルすることです。これにより、より効率的に評価できます。
obj := 3.
msg := '[:x | x + 5]'.
block := Compiler evaluate: msg.
result := block value: obj.
ところで、上記(および下記)のコードはSqueak用ですが、他のSmalltalkではコンパイラにアクセスする方法が異なる場合があります。
文字列から直接変数にアクセスできる、さらにハック的な方法があります。これは、コンパイルされたコードを「thisContext」で実行することによるものです(この場合、ワークスペースでも一時変数を宣言する必要があります)。
| obj msg result |
obj := 3.
msg := 'obj + 5'.
result := Compiler new evaluate: msg in: thisContext to: nil.
ただし、この最後の手法はお勧めしません。実行は、コンパイラを使用するよりも一般的に安全です。とは言うものの、それはいくつかの深刻なメタのものを実装するために使用することができます。例えば:
| obj |
obj := 3.
'The result is {obj + 5}.' expand
「expand」メソッドの実装は、好奇心旺盛な読者に任されています;)