Сериализация блока как строки и выполнение строковых манипуляций, хотя и удобно, также довольно опасно, если у вас нет четкого представления о содержимом блока.
Звучит так, как если бы выхотелось бы иметь возможность манипулировать AST блока - дать блок, разобрать его, изменить структуру (в данном случае заменить литерал), а затем скомпилировать измененную структуру.Для этого вы можете сделать что-то вроде этого:
| aBlock ast |
aBlock := [3+2].
ast := aBlock decompile.
ast statements first receiver: (DecompilerConstructor new codeAnyLiteral: 4).
aBlock := (Compiler evaluate: ast printString) first.
aBlock value. "==> 6"
Обратите внимание, что мы на самом деле не изменяем aBlock, а создаем мутированную копию aBlock.
Этот принцип применяется в более общем плане: декомпилировать блок, выполнить манипуляции (например, изменить селектор на полпути по цепочке отправок сообщений), скомпилировать новое дерево разбора.(Я не знаю, как из рук в руки компилировать дерево напрямую , а не оценивать распечатанное дерево, но я уверен, что есть способ.)
(Предостережение: I 'Вы написали выше в Squeak. Я не знаю, как обстоят дела с Opal, новым компилятором Pharo, так что, возможно, в Pharo вы сделаете что-то немного другое.)