Enhanced local functionality

The local operator in perl is an indispensable tool for developing exception-safe code, but it has two major limitations:

  1. it does not allow to introduce local values for objects or arrays accessible via references
  2. the only time point when the previous value is restored is the end of the lexical scope containig the local operator

polymake has two extensions allowing to overcome these limitations:

local_scalar(var, new_value); local_array(var, [ new_values ]); local_hash(var, { new_values }); local_sub(var, \&new_code);
Work analogously to the standard local operator, but allow var to be an arbitrary expression resulting in a reference or a glob pointing to the item (scalar, array, etc.) to be temporarily changed.
new_value in the scalar case can be an arbitrary expression as well, which is evaluated in scalar context. Other functions require the new value to be a reference of the corresponding type.

Explicit localization scope

An object of the class Poly::Scope can be used to define a localization scope different from the default (the enclosing lexical scope.)

$scope=new Poly::Scope; ... $scope->begin_locals; local $x=123; local_array($y, [ 4,5,6 ]); ... $scope->end_locals;

All localized updates made between begin_locals and end_locals survive the end of the lexical scope, they are reverted only when the object pointed by $scope is being destroyed. As shown in the example, you can use both standard local operators and the local_* functions described above. One Poly::Scope object can be used to gather the localizations arbitrarily many times.

Registering delayed actions

The object of the class Poly::Scope serves also another purpose: it has several queues for descriptors of different delayed activities. Later on the object may be asked to run all the collected activities. You can see this as an extension of the END subroutine concept.

$scope->at_end->{KEY}=ACTION; $scope->cleanup->{KEY}=ACTION;

Register some action for later execution. The at_end queue is activated when the $scope->end method is called. The cleanup queue is activated during the destruction of the $scope object; it is intended for exception-safe cleanup operations, just as the name suggests.

KEY is an arbitrary string used to identify the action. To avoid conflicts, different packages should use their names as prefixes in the key, unless it is purposely shared. Another good option is to use an object reference.

ACTION is a descriptor, containing all necessary information to perform the action. The following data formats are supported:

ACTION is ... operation performed
code reference code->(KEY)
object reference object->finish(KEY)
[ code reference, args ... ] code->(KEY, args)
[ "method", object reference, args ... ] object->method(KEY, args)

There is a global variable $main::scope defined in the polymake script. It is initialized with a fresh Poly::Scope object whose lifespan extends over exactly one user cycle, that is, interpreting one complete user input line in the interactive mode or executing the user script in the batch mode. The end method is called immediately before the end of the cycle.

Currently this variable is used by all visualization back-ends, they postpone the launch of the visualization program to the end of the user cycle. Other important activity is the deletion of the temporary properties created during the cycle.