1

y:=3。z:=4。
h:= '[x:= y+z.]'.
(BlockClosure readFromString: h) 値。

smalltalk 構文で文字列を取得しようとしてブロックに入れて実行しようとしているこのコードがありますが、次のようなエラーが表示されます:
未処理の例外: メッセージが理解されていません #+


h:= '[x:= 3+4.]' のようなことをすると。
(BlockClosure readFromString: h) 値

それはうまく動作します。なぜこれが起こっているのかわかりません。y は何も指しておらず、 + メソッドを理解していないと推測しています。しかし、ブロックが y と z を自由変数として扱わないのはなぜでしょうか?

4

3 に答える 3

4

あなたの問題は、実際に文字列をブロックにコンパイルするコンテキストでは y と z がわからないことです。おそらく、次のような方が良いでしょう。

h := '[ :y :z | x := y + z]'.
(BlockClosure readFromString: h) value: 3 value: 4.

x はどこにも宣言されていないため、コードもおそらく機能しないと思いますが、より正しいバージョンは次のようになります。

h := '[ :y :z | y + z]'.
x := (BlockClosure readFromString: h) value: 3 value: 4.

ブロックの文字列表現を、変数にアクセスできず、コンパイルに失敗するため、解析されたコンテキストで真のクロージャーのように機能させる実際の方法はないと思います。

于 2013-10-25T04:06:49.660 に答える
3

本当にこれを行う必要がある場合は、次のことを試してください。

   | x y z h block |
   y:=3. z:=4.
   h:= '[x:= y+z.]'.

   block := Compiler new
      evaluate: h
      in: thisContext
      allowReceiver: true
      receiver: self
      environment: self class environment
      notifying: nil
      ifFail: [self error: 'Failed to compile'].

   ^block value

ただし、問題を解決するためのより良い方法を見つけることをお勧めします。実行中のメソッドのコンテキストで文字列を動的にコンパイルするのは非常にトリッキーで、もろくなる可能性があります。

于 2013-10-25T15:52:43.167 に答える
1

James Robertson は最近、Dynamic Code Generation に関する彼のブログに投稿しました。役に立つかもしれません。

于 2013-12-27T18:32:03.957 に答える