Skip to main content

Script variables

Script variables are variables created directly inside a script rather than in the Variables view.

Script variables are useful for defining derived or hard-coded values only once (as a variable), so that you can then refer to that variable repeatedly elsewhere in your project. Creating variables directly inside a script can also make your ATL easier to follow.

Tip

See Key Concepts > Variables for guidance on creating variables in the Variables view.

Index

Local and global script variables

A script variable can have local or global scope.

Local scope means that the variable is accessible only within the ATL block in which it's defined. Global scope means that it's accessible anywhere within the project once it has been defined.

A script variable is defined (i.e. created) when a value is first assigned to it — for example, the statement Target = 3500000 in the example below. If you try to read or print the value from a variable before it is defined, you get an error message.

Example — Local script variables

KC_scriptVariables_1.png

A local script variable is accessible only within the ATL block in which it's defined. The ATL block above comprises two parts. The first part (highlighted) defines a local variable called Target. The second part is a conditional statement that uses the Target variable.

Because the conditional statement is within the same ATL block as the statement defining the Target variable, it can use Target as a local script variable. If the conditional were outside the block where Target is defined, you would get an error message.

Note that if there already existed a global script variable called Target, the statement Target = 3500000 would NOT create a local variable; instead, it would assign the 3500000 value to the global variable. In such a case, to ensure a local variable, use the local. prefix.

Important

Best practice is to avoid creating global and script variables with the same name.

For further guidance, see Scope rules for script variables.

It’s common to use local script variables when writing a user-defined function. For example:

KC_scriptVariables_2.png

The ATL block is the function body for a user-defined function. Three local script variables — cityData, cityDataForPeriod, and salesForPeriod — are defined and subsequently used within the block to generate a total sales figure. The color underlining does not appear in Studio.

Example — Global script variables

To define a global script variable, you must use the global. prefix. Once it's defined, you can reference the variable elsewhere without the prefix. Crucially, you can use global script variables outside the ATL block in which they are defined.

KC_scriptVariables_3.png

The script above has five ATL blocks. The first defines the variable topBranches, which is then used in the next four ATL blocks. If topBranches was defined as a local script variable, the subsequent references to the variable would produce errors.

One problem with the script above is that the first ATL block — which defines the topBranches variable — will output a multi-level list, which you don't want printed in your output narrative. You can avoiding this by suppressing the output.

Suppressing the output of a script variable

Sometimes you want to define a global script variable and assign a value but NOT print that value at that point in your script. In other words, you want to suppress the variable's output.

An ATL block can contain multiple statements, and its return value is always the value of the last statement. Therefore, you can suppress a script variable's output by (1) adding an extra statement, and (2) making that last statement an empty string. For example:

KC_scriptVariables_4.png

This script contains five ATL blocks. The first defines the variable topBranches, which is then used in the next four ATL blocks.

The first block contains two statements, separated by a semicolon. The first defines the variable and the second (underlined) contains the syntax for an empty string. Making the last statement an empty string ensures that nothing is printed for the first ATL block.

Scope rules for script variables

Although you can give local and global script variables (and user-defined variables in the Variables view) the same name, we strongly recommend that you don't. Having duplicate names makes it too easy to introduce bugs to your project.

If you use the same name for a global and local variable, you can reduce the risk of bugs by using the global. and local. prefixes. If you choose NOT to do this, you should know how Studio handles identically named variables at different scopes. See the guidance below.

  • Each project has a global scope. Global script variables live in the global scope and are accessible within all other scopes. Once defined, they are live during the entire narrative-generation runtime.

  • User-defined variables (those created in the Variables view) also reside in the global scope, but these are immutable. They are evaluated when first referenced, and their values are fixed for the rest of the narrative generation process.

FOR SCRIPT VARIABLES ONLY:

  • Each script can access variables defined in the global scope.

  • Each script has its own local scope. When running Script A, you can access all local variables defined in Script A, but not the local variables described in Script B, Script C, etc. All defined variables in the global scope are available.

  • Each ATL block has its own scope as well as access to the variables of all parent scopes within the same script.

  • Script variables are defined when they are first used on the left side of an assignment expression.

  • To define a global script variable, you must use the global. prefix — for example, global.totalSales = sum(SalesList).

  • You can define a local script variable two ways:

    1. By not including a prefix — for example, totalSales = sum(SalesList).

    2. By using the local. prefix — for example, local.totalSales = sum(SalesList).

    You should use the local. prefix when your script already has a global script variable with the same name. Otherwise, you risk assigning a new value to the global script variable. For example:

    ATL in Script

    Result

    Notes

    [[global.target = 50000; target = 30000;'']]
    
    [[abbreviateNumber(currencyFormat(target))]]    

    $30K

    target = 30000 assigns a new value to the global script variable.

    [[global.target = 50000; local.target = 30000;'']]
    
    [[abbreviateNumber(currencyFormat(target))]]    

    $50K

    local.target = 30000 defines a local script variable. The value assigned to the global script variable is unchanged.

  • The expression evaluation for non-prefixed script variables, including assignments, uses the innermost variable definition. Therefore:

    • Local rather than global when both exist.

    • Inner local variable rather than a local variable from a parent scope.

    • Global variable when no local variable exists.

  • If an assignment refers to an undefined variable on the left side of the assignment, the interpreter defines the variable in the current scope, unless you have used the global. prefix.

  • The above point applies only when the left side is an identifier (e.g. x = 7). Indexed assignments (e.g. x[2] = 7) and assignments to nested fields (e.g. x.sales = 7) that refer to undefined variables are themselves undefined, so they generate a major warning.

  • If a variable on the right side of an assignment (or any other expression) refers to an undefined variable, it generates a major warning.

  • When you define a global script variable, any identically named local script variables that exist at that point are deleted. However, when you assign to an already defined global variable, no local variable is affected.