Variables and Variable Scope(4.3)

Variables in APL may be either global or local:

  • Global - Declared outside functions and function blocks
  • Local - Declared in a function or function block

// Declaration without initialization
int myInt1;
//Declaration with initialization
int myInt2 = 42;

The declaration order of variables is relevant for the initialization in the sense that earlier variables may be used as input to later variables.

Example - Declaration order of global variables

// Legal
int f1 = 1;
int f2 = f1 + 1;

// Illegal! The following will not compile!
int f3 = f4 + 1;
int f4 = 1;


The scoping rules are as follows:

  • Global variables are available in all functions and blocks. Note that they cannot be accessed from another agent or by an external APL script.
  • All blocks define a separate scope.
  • Any non-anonymous block statement (statements within a {} block) defines a scope.


Example - Scope

int a; //Variable a is global

consume {
	int b; //Variable b is local to the consume block
    {
        //anonomous block
        int c; //Variable c is local to the consume block;
    }
    for(int d=0;d<10;d++) {
        //Variable d is local to the for-loop
    }
   
}

'Variable hiding' is not allowed. For instance, if a variable myVar has been declared in global scope, it is not permitted to declare another variable myVar anywhere else in the code.

Example - 'Variable hiding' is not allowed

int myVar;
consume {
   if (true){
      int myVar; //illegal! myVar is already declared as a global variable 
   }
}


Example - 'Variable hiding' is not allowed

consume {
   int myVar;
   if (true){
      int myVar; //illegal! myVar already declared before on a higher level
   }
}


Example - 'Variable hiding' is not allowed

consume {
   if (true) {
      int myVar; //myVar will only be valid within this block
   } myVar = 2; //illegal! myVar does not exist here
   if (true) {
      int myVar; //myVar can be declared again as it is in a separate scope from above
   }
   int myVar; //ok! since it is a separate scope from above
}

For the built-in function block variables, such as the input variable in the consume block, ‘Variable hiding’ is allowed.

Final Variables

To prevent variables from being changed, the final keyword is used:

final int myVar = 100;

Note!

Only numeric and string types are supported for final variables. 

Persistent Variables

Note!

Applicable for batch workflows only.

All variables are by default reset between workflow activations. However, if a value of a global variable has to be saved between each activation, the persistent keyword can be used. The variable declaration as follows:

persistent int myVar = 100;

Persistent variables are read from the database between initialize and beginBatch and saved between endBatch and deinitialize. Consequently, any assignment to the persistent variable in initialize only works the first time, once you have a persistent value this will overwrite the value from initialize. Like all other variable types, persistent variable names are unique for each agent within a workflow.

Note!

A persistent variable cannot be altered after it has been entered into the database. It will be kept there until the workflow is removed or the value is overwritten, that is, when the workflow configuration is saved with a new name using the Save As... option.

Example - Persistent variables

persistent int counter;

initialize {
  counter = 0;
  debug( "Value in initialize: " + counter );
}

beginBatch {
   counter = counter + 1;
   debug( "Value in beginBatch: " + counter );
}

The debug output from initialize will read zero each time, while the debug output from beginBatch will read the actual value.

First time activated (one input batch):

Value in initialize: 0

Value in beginBatch: 1

Fifth time activated (one input batch):

Value in initialize: 0

Value in beginBatch: 5