Variables - Advanced Documentation

<< Click to Display Table of Contents >>

Navigation:  Advanced Features > Scripting > Advanced Scripting >

Variables - Advanced Documentation

What is a variable?

A variable is a scripting token that allows you to access a value using a custom name of your choice.
 Examples:

     //assign 1.23 to a global variable name Variable1

Variable1 = 1.23

 

//define a local variable named MyName and assign the value John

     Set MyName = John

               

There are several types of variables within Vertex that differ in the way they are created, assigned, or used.

Global Variables

Global variables are managed just like other so-called “core objects”: they can be created via the Create menu and are listed in the Project Explorer where they can be organized into collections or selected for editing in the Inspector.

The generic name of global variables in the Project is “Variable”.

The value of a global variable is synchronized between alle Session Members, just like the properties of other core objects.

This is called a “global scope” because the variable’s value can be accessed/shared globally between all scripts and Session Members. In contrast to “local scope variables” that are only accessible within the script for which they have been defined.

Global variables cannot be created within a script, they must be added to the Project manually. Once they have been created, they can be accessed as follows:

 

                Assumptions: Project contains Variable1 with the custom name “MyValue”, Variable2

 

     //assign a value using the `Value` member of the Variable object:

     Variable1.Value = First Value

 

     //assign a value using the shorthand-syntax

     Variable2 = Second Value

 

     //log the value using the full syntax

     Log Variable1.Value

 

     //log the value using the shorthand-syntax

     Log Variable2

 

     //assign the value using the custom name and the full syntax

     MyValue.Value = First Value Override

 

     //log the value using the custom name and the shorthand-syntax

     Log MyValue

 

 

The value of a global variable is essentially always a String because it must be synchronized between Session Members and be easily editable in the Inspector – it cannot contain a reference to a core object, e.g. Sequence.

Every value assigned to a global variable will be converted to its String representation – in the case of a Sequence, the sequence’s name. Consider this example:

 Assumption: Project contains Sequence1 with the custom name “MySequence”, Variable1

 

Variable1 = Sequence1
Log Variable1

 

              Output:

     MySequence

 

 

While object references cannot be resolved, several other “value types” can be converted to Strings and back again. This includes but is not limited to Numeric, Json, Array and Dictionary values.

 

Notes for upcoming chapters:

Global variables can be used in Indexers because their value is available during the pre-processing stage of a Script in which the Indexers are evaluated.

Global variables support type-specific features by using the “As…” members of the variable.

Local Variables

Local variables are variables that are defined within a script and that can only be used/accessed during the execution of that script.

Local variables are defined using the `Set` method:

 

 Assumption: Project contains Sequence1 with the custom name “MySequence”

 

     //define a local variable and assign a value

Set MyVar = 1.23

     

//change the value to string

MyVar = Example Text

 

//assign Sequence1

MyVar = Sequence1

 

Log MyVar

 

 Output:

MySequence

 

 

In contrast to global variables, local variables are not restricted by their String representation: local variables can reference any type of object; when the value is consumed it will be converted if and as required.

In the above example, using `Set`, a local variable is declared without specifying a type. Later, Sequence1 is assigned to the variable and the value is logged: the result is “MySequence” which is the default string representation of a Sequence (custom or default name).

It is also possible to specify the type using one of the `Set` members as in this example:

 

Set.Text a = 0001.23000
Log a
 
Set.Numeric b = 002.3400
Log b

 Output:

0001.23000

2.34

 

As you can see, specifying the type during declaration changes the way the value is parsed and stored.

Local variables declared with a specific type will always convert all input into that type (if possible) and return a value of that type. These variables also have type-specific members, e.g.:

 

Set.Text a = 0001.23000
Log a
Log a.Contains 23
 
Set.Numeric b = 002.3400
Log b
Log b.Ceiling

 

 Output:

0001.23000

True

2.34

3

 

Local variables are available within the scope of the script once they have been defined. If used before, they will be parsed as literal values as shown here:

 

log a
set a = 123
log a

 

 Output:

a

123

 

Notes from upcoming chapters:

Local variables cannot be used in Indexers because their value is not available during the pre-processing stage of a Script in which the Indexers are evaluated.

Local variables declared without a specific type support type-specific features by using the “As…” members of the variable.

Local variables declared with a specific type only support the type-specific features of that type.

 

Script Parameter Variables

Script Parameter Variables are variables with a „slightly larger than local” scope: they are only valid within the script for which they are defined, but are initially set from the outside – via parameters that are passed to a custom Script.

 

Once the parameters have been defined for a Script, the associated variables can be used just like normal local variables that were defined without a specific type.

 

Script Parameter Variables are only available for custom Scripts that define one or more parameters. This can be done in the Inspector when inspecting a custom Script or in the Script Editor: when the script is selected, an input box for specifying the parameters is shown in the status bar at the bottom of the editor.

 

Consider the following when defining parameters:

The parameters are entered into a single-line text input box, with multiple parameters separated by a non-word character, e.g. space, comma, semicolon.

The names are case-insensitive (as all script processing is).

You can enclose a parameter name in double-quotes to declare the parameter will not be parsed, but instead used as a literal string; see the output in the following example:

 

 Script1, without parameters:

         Set V1 = 1.234

Set V2 = 5.678

 

   Script2 V1, V2

 

 Script2, with parameters "Para1", Para2:

     Log Para1

     Log Para2

               

Output when running Script1:

     V1

     5.678

 

Due to the first parameter being defined by a name in double quotes, "Para1", not like Para2, the parameter (here: V1) is not parsed, but used as a literal for the value of the script parameter variable.

 

Notes from upcoming chapters:

Script parameter Variables can be used in Indexers because their value is available during the pre-processing stage of a Script in which the Indexers are evaluated.

Script parameter variables support type-specific features by using the “As…” members of the variable.

 

Type-Specific Members

Certain value types are supported by offering type-specific methods and properties for evaluating or modifying values because, e.g., a method for splitting strings is not useful for numeric values.

 

These are the types currently supported:

Array  

several items that can be accessed by the 0-based-index position within the items.

Dictionary

several key-value-pairs, i.e. values that can be accessed by their associated key.

Json

a JObject or JArray instance.

Numeric

a numeric value; internally stored as `double`.

Url

a string that represents a Url (http://...).

Xml

a string that represents a Xml element.

 

 

As described before, these types can be assigned when declaring a local variable as also shown in this example:

 

 Assumption: Project contains Sequence1 with the custom name “MySequence”, Sequence2

set.Array a = Sequence1, Sequence2
log a
 
set.Dictionary d = one:1,two:2,three:3
log d
 
set.Json j = {"Name":"John", "Age":23}
log j
 
set.Numeric n = 0123.456000
log n
 
set.Text t = 0123.45600
log t
 
set.Url u = http://www.google.de/search?q=ioversal
log u
 
set.Xml x = <root><item id="1"/><dawg test="3"/> <item id="2"/></root>
log x
 

         Output:

MySequence, Sequence2

one: 1, two: 2, three: 3

{"Name":"John","Age":23}

123.456

0123.45600

http://www.google.de/search?q=ioversal

<root>\r\n  <item id="1" />\r\n  <dawg test="3" />\r\n  <item id="2" />\r\n</root>

 

Note how converting the values to loggable strings effects the output:

-Sequence1 is logged as “MySequence”.

-Numeric types do not store leading/trailing zeros.

-Text type maintains leading/trailing zeros.

-Xml elements are formatted when serialized.

 

For local variables without a specific type or global variables there are helper methods that convert the value to the required type and offer the same methods as type-specific local variables, e.g. “AsJson”:

 

set.Json a = [{"Name":"John", "Age":23}, {"Name":"Bob", "Age":24}, {"Name":"Pete", "Age":20}]
 
log a.Get 0/Name
log a.Get 0/Age
 
set b = a
log b.AsJson.Get 1/Name
log b.AsJson.Get 1/Age
 

Output:

John

23

Bob

24

 

 

DynamicValue Member

Local variables that do not have a specific type, including Script Parameter Variables, offer a helper method, DynamicValue, for accessing members of the value referenced by the variable:

 

            Assumptions: Project has Sequence1 with ClipContainer1

 

 set s = Sequence1.ClipContainer1
 
 log s.DynamicValue.Opacity
 
 set p = Sequence1.ClipContainer1.Transform.Position
 
 log p.DynamicValue.X
 log p.DynamicValue.Y
 log p.DynamicValue.Z

 

As you can see, you can assign any object or property to a local variable and then access that instance using `DynamicValue`.

 

Notes from upcoming chapters:

-DynamicValue is often used when working with Loops.

 

Comparing Global and Local Variables

 

Consider these examples that demonstrate the difference between local variables (incl. script parameter variables) and global variables.

 

Example1: Storing a core object in a global.

 

              Assumptions: Project contains Variable1, Sequence1

 

Variable1 = Sequence1
 
Set s = Variable1

//since the dynamic value cannot be resolved for the string stored within Variable1, the literal expression will be logged

Log s.DynamicValue.AudioOffset
 
Set s = Sequence1

//the dynamic value can be resolved because a local variable can reference the actual object
Log s.DynamicValue.AudioOffset

 

Set s2 = s

//the dynamic value can be resolved because a local variable can reference the actual object
Log s2.DynamicValue.AudioOffset

 

 

 Output:

s.DynamicValue.AudioOffset

0

0

 

The above example demonstrates that an object reference cannot be stored and retrieved from a global variable: when assigning Sequence1 to Variable1 only the string representation is stored – and this is not converted back to an object when being used.

 

During the processing of `Set s = Variable1` the assignment expression (`Variable1`) is parsed resulting in the stored string (“Sequence1”). A recursive/nested parsing of the string result is not done at this point.

 

Example2: Storing a Dictionary in a global variable.

               

 Assumptions:  Project contains Variable1

 

//the expression is parsed and stored as an actual dictionary
set.Dictionary d = a:1,b:2,c:3
 
//a string representation of the dictionary is stored 
Variable1 = d
 
//an actual dictionary is parsed from the value 
set.Dictionary d2 = Variable1
 
log d2.Count

 

//the actual value is maintained (not converted) when assigning to an unspecific local variable

set d3 = d2

 

//use the AsDictionary member to access the methods for this type
log d3.AsDictionary.Count

 

 Output:

3

3

 

The above example demonstrates that certain supported types, e.g., a Dictionary, can be converted to and from a global variable successfully.

 

Working with enumerable values (Array, Dictionary, JSON)

Enumerable values, represented by Array, Dictionary and JSON have a few special methods that are worth looking into.

Note: Enumerable values are commonly used in connection with Loops (s. below) and the DynamicValue member (s. above). This chapter focuses solely on the special methods available for enumerables.

These methods are Where, OrderByAsc, OrderByDesc, and Select as shown in the following example (details will be explained further below):

 

                Assumptions: Project contains contents RedPng, GreenPng, BluePng

 

set.Array items = RedPng, GreenPng, BluePng
log items
 
set a = items.Select i => i.UserProperties.Id
log a
 
set b = items.OrderByAsc i => i.UserProperties.Id
log b
 
set c = items.OrderByDesc i => i.UserProperties.Id
log c
 
set d = items.Where i => i.UserProperties.Id < 33
log d

 

                Output (example):

Red.png, Green.png, Blue.png

34, 32, 2

Blue.png, Green.png, Red.png

Red.png, Green.png, Blue.png

Green.png, Blue.png

 

What makes these methods “special” is the use of a so-called “anonymous function”, e.g.: i => i.UserProperties.Id

In the Vertex Scripting context “anonymous functions” are nameless, single-line functions that have one parameter and a return value:

The name of the parameter (that is to be used in the function) is an arbitrary custom name, specified on the left-hand side of `=>`, in the example above: `i`

The function is defined by the remaining text on the right-hand-side of `=>`, in the example above: `i.UserProperties.Id`

 

These functions, used by the methods mentioned above, which are all only applicable to variables representing enumerable items (Array, Dictionary, JObject, JArray) are called for each item, assigning the item to the defined parameter (in the example above: `i`)  so that it can be used for evaluation. The way, in which the functions are evaluated, and their results used, depends on the method context.

 

In all cases, the methods do not alter the source variable, but instead return a new enumerable instance:

Where: The result is expected to be true or false, and only items for which the result was true will be added to the result set.

OrderByAsc, OrderByDesc: The results (of all items) are used to return a version of the original items, sorted in ascending or descending order, respectively.

Select: A new Array is created, using the function results as items.

 

Since the contents of the enumerable variables can be of any (and different) types, the Script Editor cannot offer Code Completion support. All members of the anonymous function parameter (in the example above: `UserProperties.Id`) will be parsed as if they had been amended to the source of the parameter (here: a content core-object).

 

Note: There are other members (e.g. Count, Take, Skip, ByIndex, ByKey) that also only apply to enumerable variables, but they do not require anonymous functions.