Publication date: 07/08/2024

Scoping Operators

In JSL, using scoping operators is an easy way to help JMP resolve ambiguous names (for example, when a name refers to both a variable and a column name).

In the following example, the prefix double-colon operator (::) identifies z as a global variable. The single-colon prefix operator (:) identifies x and y as column names.

::z = :x + :y;

Tip: The Names Default to Here(1) function also affects name resolution. See Names Default To Here and Global Variables.

Two JSL functions are interchangeable with scoping operators. Table 5.4 describes the functions and syntax.

Table 5.4 Scoping Operators

Operator and Equivalent Function

Function Syntax

Explanation

:

As Column

: name

dt : name

As Column(dt, name)

Forces name to be evaluated as a data table column. The optional data table reference argument, dt, sets the current data table. See Scoped Column Names for examples.

::

As Global

:: name

As Global(name)

Forces name to be evaluated as a global variable.

Note: The double-colon is also used as an infix operator to represent ranges.

Scoped Column Names

Scoping column names is the simplest way to prevent conflicts with variable names. Use scoping operators to force names in a script to refer to columns.

1. The prefix colon (:) means that the name refers to a table column or table variable only, never a global variable. The prefix colon refers to the current data table context.

:age;

2. The infix colon (:) operator extends this notion by using a data table reference to specify which data table has the column. This is particularly important when multiple data tables are referenced in a script.

In the following example, the dt variable sets the data table reference to Big Class.jmp. The infix colon separates the data table reference and age column.

dt = Data Table( "Big Class.jmp" );
dt:age // The colon is an infix operator.

As Column() achieves the same results:

dt = Data Table( "Big Class.jmp" );
As Column( dt, age );

Therefore, the following expressions are equivalent when only Big Class.jmp is open:

:age;
As Column( dt, age );
dt:age;

The Column function can also identify a column. For Big Class.jmp, the following expressions all refer to age, the second column in the table:

Column( "age" );
Column( 2 );
Column( dt, 2 );
Column( dt, "age" );

Prevent Column Name and Variable Name Conflicts

To avoid conflicts, use unique column and variable names or scope the names.

When a global variable and a column have the same name, the global variable name takes precedence. In this situation, you must scope the column name.

::age = [];
age = :age << Get As Matrix;

To avoid ambiguity between the global variable and column name, scope both variables.

::age = :age << Get As Matrix;

If more than one data table might be open, assign data table references to variables. Scope your columns to the appropriate table.

dt1 = Open( "$SAMPLE_DATA/Big Class.jmp" );
dt2 = Open( "$SAMPLE_DATA/Students.jmp" );
::age = dt1:age << Get As Matrix;
::height = dt2:height << Get As Matrix;

Note that JMP evaluates column formulas through each consecutive cell of the column, so scoping the column name is usually unnecessary. However, if a variable assigned in a formula has the same name as a column, you must scope the column name. See Scoped Names.

Tip: The Names Default to Here(1) function also affects name resolution. See Names Default To Here and Global Variables.

Unscoped Column Names

Sometimes an unscoped name gets or sets a value. JMP resolves it as a column in a data table (rather than a global variable) under these circumstances:

if no global variable, local variable, or an argument using that name already exists,

and the data table in context has a column of that name,

and

either the current row is set to a positive value

or the name is subscripted (for example, the subscript [1] in weight[1] selects the first value in the weight column).

Exception

In column formulas and Nonlinear formulas, column names take precedence over global variables.

Set the Current Data Table Row

By default, the current row is 0, an illegal row number. So the following expression assigns a missing value to the ratio global variable:

ratio = height / weight;

Specify the row number with the Row() function. In the following example, the row is set to 3. The height in that row is divided by the weight, and the result is assigned to the ratio global variable.

Row() = 3;
ratio = height / weight;

Another possibility is to use subscripts to specify the row number. The following expression divides the height in row 3 by the weight in row 4.

ratio = height[3] / weight[4];

Specifying the row number is unnecessary when the script iterates a row at a time down the whole column. The following example creates the ratio column. For each row, the height is divided by the weight.

dt = Open( "$SAMPLE_DATA/Big Class.jmp" );
dt << New Column( "ratio" );
For Each Row( :ratio = height / weight );

JMP evaluates formulas and calculates pre-evaluated statistics iteratively down a column. In these instances, identifying the row number is also unnecessary. (Pre-evaluated statistics are single numbers computed from the data table, as discussed in Pre-Evaluated Statistics.)

Name Resolution in Automatically Run Scripts

In an Open() function, you can specify that the script run automatically when it’s opened.

Open( "$MY_SCRIPTS/A.jsl", Run JSL( 1 ) );
Open( "$MY_SCRIPTS/B.jsl", Run JSL( 1 ) );

You can also type //! on the first line of the script to run the script automatically.

In these instances, the only shared names between A.jsl and B.jsl are globals and namespaces (not here and not local).

To apply the names in A.jsl to B.jsl, include B.jsl in A.jsl instead of opening and running both scripts.

Include( "$MY_SCRIPTS/B.jsl" );
Want more information? Have questions? Get answers in the JMP User Community (community.jmp.com).