Programmatic code evaluation

To evaluate an expression programmatically a developer should use GtPharoSnippetCoder GtPharoSourceCoder subclass: #GtPharoSnippetCoder instanceVariableNames: 'behavior' classVariableNames: '' package: 'GToolkit-Pharo-Coder-Method-Coder' . A snippet coder provides developers with a good control over execution parameters and assists them with retrieving an evaluation result value or an exception.

A context-free expression is an expression the evaluation result of which does not depend on a runtime context. Such expressions do not reference self, and do not depend on external variables. In this simple case we can directly evaluate an expression, for example:

coder := GtPharoSnippetCoder forSource: '2 + 2'.
coder doItAll
  
coder := GtPharoSnippetCoder forSource: 'Object new'.
coder doItAll
  

To evaluate any context-sensitive expression a developer should first create an evaluation context. That evaluation context can be parametries with runtime values. Once the context is setup it can be used to evaluate an expression.

coder := GtPharoSnippetCoder forSource: '2 + 2'.
context := coder evaluationContext.
coder doItInContext: context
  

Sometimes it is desired to provide an expression with an input variable. The following snippet shows how we can provide a value for a local variable that will be used during evaluation (GtLocalVariablesBindings Object subclass: #GtLocalVariablesBindings uses: TGtVariablesBindings instanceVariableNames: 'bindings' classVariableNames: '' package: 'GToolkit-VariableBindings-Bindings' ):

coder := GtPharoSnippetCoder forSource: 'number * 2'.
context := coder evaluationContext.
context addBindings: (GtLocalVariablesBindings new
	localAt: #number put: 42).
coder doItInContext: context
  

By default, special reserved variables such as self, super and thisContext are not bound to anything. In order to use self within the expression it is neccessary to setup a receiver object and declare reserved variables bindings (GtReservedVariablesBindings Object subclass: #GtReservedVariablesBindings uses: TGtVariablesBindings instanceVariableNames: '' classVariableNames: '' package: 'GToolkit-VariableBindings-Bindings' ):

coder := GtPharoSnippetCoder forSource: 'self * 2'.
context := coder evaluationContext.
context receiverObject: 42.
context addBindings: GtReservedVariablesBindings new.
coder doItInContext: context
  

If a context-sensitive expression uses slots (or instance variables) of a bound object it is required to specify an additional set of bindings designed to read the value from the slots of an object (GtSlotVariablesBindings Object subclass: #GtSlotVariablesBindings uses: TGtVariablesBindings instanceVariableNames: 'object' classVariableNames: '' package: 'GToolkit-VariableBindings-Bindings' ):

coder := GtPharoSnippetCoder forSource: 'bounds class'.
context := coder evaluationContext.
context receiverObject: BlElement new.
context addBindings: (GtSlotVariablesBindings new object: context receiverObject).
coder doItInContext: context