Snap variables -- similar to variables in other programming languages -- store values to be referenced later. A common reason to use a variable is to have a single place where a value is specified, and referencing that variable in multiple places afterwards. That way, if you need to change the value being passed in those places, you only need to change it where the variable is defined. Another reason is to store a value which needs to be "built up" or changed in more than one line of code.
Variables must first be defined, meaning you specify a name and initial value (if any). Later, you can use the get and set blocks to reference the variable.
Declaring a Variable
Variables must be defined using the declare block. They do not exist until they are declared. Variables are given a name (in yellow), a datatype (selected from a drop-down list of types), and can be given a default value. For example, declare a new variable called "foo" to store text, and populate it with the initial value of "bar".
After the variable is declared, its name appear as an option in the get and set blocks, used to read and write values. Snap is a strongly-typed language: any new value you "set" into a variable must have the same data type they were defined with.
Scoping
Variables are scoped, meaning they are only accessible within the realm they are defined in. Generally speaking, when you define a variable, it will only be accessible
Finding References and Definitions
- after its definition block
- within the same context as its definition block
For example, consider the "foo" variable used in this Value Rule. It is declared once, and used 4 times. But three of those times, the reference is an error (it's bright orange), and must be fixed:
First, note the definition block is contained within an if statement. Since a variable's scope is "within the same context as its definition block", we know that "foo" only exists within that if statement. Once we reach the else clause, "foo" no longer exists. Therefore:
- The first orange block is an error, because we are trying to use the variable before we declare it.
- Line 4 works fine: we are using the variable after we declared it, and in the same context as the declaration.
- The second orange block is an error, because we are no longer in the same context of the "if" clause.
- The last orange block is also an error, because we are well outside the context of the "if" clause.
To access the variable outside of the if statement, you can move the define block to just above the if block, which will increase its scope to the closure outside of the if statement.
To access a variable throughout a rule, declare it at the top of the rule, after the start block.
If you wish to access a variable across many rules of the same type, declare it in the first rule of that type. It remains in scope through all the remaining rules of that same type. For example, your first value rule in a configurator could be called "declarations" and do nothing but declare the variables you will use throughout the rest of those value rules.
Variables cannot be used across rules of different types. For example, a variable declared in a Value rule is out of scope to all the Validation rules, and vice versa. To share a value across rules, store the value in a field. Fields are not only a way for your user to provide information, they are also globally persistent variables. This means any information in a field is visible to all rules (global), is stored when the configurator is saved (persistent), and can be changed as many times as you like (a variable). Data of any type and reasonable size is easy to serialize into JSON, and store in a text field in your configurator. Here's an example of data serialization.
Note that variables can be named identically if they each belong to a disparate scope; however, they cannot be named identically if one overlaps the scope of another variable.
In certain cases, especially in configurators, variables can be declared in one rule, and then referenced in another. This can make following variables challenging, especially if you have identically named variables declared in different scopes.
Snap includes a way to find references to declared variables.
On the block that declares any variable, right-click for the context menu then select "Find All References". Clicking Find all Variable References on this block will display a clickable list of all references to that variable.
Similarly, on any block that references a variable, you can right-click and select "Go to Definition" to find where that variable is declared. Clicking "Go to Variable Definition" will highlight the block where it is defined.