2012-05-05 2 views
4

私はオブジェクトと、それに送信したいメッセージを含む文字列を持っています。オブジェクトにメッセージを実行するように指示する方法

たとえば、整数オブジェクトに送信したい文字列 '+ 5'です。

それがワークスペースにあったなら、私は書くでしょう「OBJ + 5」、私はあなたが引数を分離することができた場合は、それが

答えて

12

...事前に文字列を知らなくても実行時間で実行する必要がメッセージ自体からのメッセージを、あなたがメッセージの送信「を実行」することができます

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のためであり、他のSmalltalksは異なる方法を有していてもよいですコンパイラにアクセスします。

文字列から変数に直接アクセスできるように、さらに邪魔になる方法があります。これは、「thisContext」でコンパイルされたコードを実行することである(この場合には、あなたは一時もワークスペースにvarsは宣言する必要があります):

| obj msg result | 
obj := 3. 
msg := 'obj + 5'. 
result := Compiler new evaluate: msg in: thisContext to: nil. 

しかし、私はこの最後の方法をお勧めしません。実行は一般にコンパイラを使用するよりも安全です。つまり、深刻なメタ情報を実装するために使用できます。コンパイラを使用したおかげで、私が行方不明になったまさにです

+0

):);「拡大」方式の例えば:

| obj | obj := 3. 'The result is {obj + 5}.' expand 

実装は、好奇心旺盛な読者に任されています – Mugen

関連する問題