Values, Variables, and Expressions
Now that you have seen the ways to filter down to the data you want to patch, and even the exact actions to do what you want to modify something, you may be wondering how to describe the ways you want to modify the data. This is where Values, Variables, and Expressions come in, these are the ways to express, store, and manipulate data within Patch Manager.
Values
Values are the most basic way to express data in Patch Manager, of which, there are a few basic types of them.
Null Values (type: none)
This type of value is best described as a lack of data, and there is only one value under this type: null
.
Boolean Values (type: bool)
This type of value holds yes/no answers, whether something is the case or not, etc..., there are exactly 2 values of this type:
- true
Represents a boolean value that is similar to "yes", or "that is the case"
- false
Represents a boolean value that is the opposite of
true
, meaning "no", or "that is not the case"
Integer Values (type: integer)
This type is the representation of mathematical integers (positive or negative numbers, without decimal points). Values of this type are usually written out as base 10 numbers, though they can also be written in base 16 with a 0x
prefix. Here are a few examples of integer values:
Floating Point Values (type: real)
This type is the closest representation to the mathematical concept of a real number (positive/negative, with decimal points). Values of this type are written out as base 10 numbers (with decimal points always). A few examples of floating point values are as follows:
String Values (type: string)
This type of value represents sequences of characters, usually forming words or similar constructs, but not necessarily. They are represented as a sequence of characters enclosed by single ('
) or double ("
) quotes, or as a sequence of alphanumeric characters (plus _/-) without quotes. A few examples are as follows:
String Escape Sequences
Sometimes though, you may want to represent characters in your strings that you can't represent normally, such as nested quotes, or a line break, or certain unicode characters, this is where "escape sequences" come in, these are sequences started by a \
that are used to represent an entirely separate character.
Escape Sequence | Replaced By |
---|---|
|
|
|
|
|
|
| A newline (ASCII |
| A carriage return (ASCII |
| A form feed (ASCII |
| A horizontal tab character (ASCII |
| A vertical tab character (ASCII |
| An alert character (ASCII |
| Unicode character number |
| Unicode character |
| Unicode character |
| Unicode character |
List Values (type: list)
This type of value represents a sequence of values, it is represented by a ,
separated list of values (of any type) surrounded by [
and ]
. A few examples are as follows:
As you can see, nested lists are allowed, and so are trailing commas.
Map Values (type: dictionary)
This type of value represents a relation of keys to values, the keys are strings that are optionally enclosed in quotes, it is represented by a ,
separated list of key: value
or "key": value
pairs surrounded by {
and }
. A few examples are as follows:
As you can see, nested dictionaries are allowed, and so are trailing commas.
Deletion Values (type: deletion)
This is a special type of value, represented by @delete
that when assigned to anything, deletes the thing it is being assigned to.
Other Types
There is actually one more value type that is considerably more advanced called a closure
explained within the Functions and Closures page.
Truthiness
Even though there is a specific bool
type that already exists, every value has a measure called truthiness, which describes how close to acting as a true
boolean value it is, if a value is acting as such it is called truthy, otherwise it is called falsy or not truthy. The following table describes the criteria for truthiness for each type of value
Value Type | Criteria for Truthiness |
---|---|
| Values of this type are always falsy |
|
|
| Values of this type are always truthy |
| Values of this type are always truthy |
| Values of this type are always truthy |
| Values of this type are always truthy |
| Values of this type are always truthy |
| Values of this type are always falsy |
Variables
Variables are the primary way to store data outside of objects, and access preexisting data as is the case with implicit variables. They are usually represented by identifiers prefixed by either $
or $$
, examples being $my-value
or $$communicationRange
. There are 2 types of variables, implicit variables, which are the aforementioned preexisting data, and user defined variables, which are variables defined to store stuff.
Implicit Variables
Implicit variables are variables that are implicitly defined in certain contexts, and may or may not exist.
$current
This variable holds the value representation of the current object you are editing with your selection block. Note: if you are editing multiple objects, each objects edit technically runs individually therefore it is a singular object
$parent
This variable holds the value representation of the parent of the current object you are editing with your selection block.
$value
This variable is defined only when doing field editing, and it is defined as the current value of the field you are editing. Useful for stuff like scaling the fields value by a number or similar.
$$... (object local variables)
This isn't a single variable, but a set of variables of the form $$field-name
that is defined as the current value of the field named field-name
in the current object. To better explain it, here are a few example usages
User Defined Variables
User defined variables are variables usually defined as such $identifier: [expression];
, where they can later be referred to by $identifier
. And now is a perfect time to go over the rules for identifiers. Identifiers are a sequence of characters that can start with a-z
, A-Z
, and _
, and then can be followed by those characters and also 0-9
, .
and -
. -
may not be the last character of an identifier, and it can only be immediately followed by a-z
and A-Z
. So _xyz-f0-f1-f23.4
is a valid identifier but 9rt-g
is not.
Modifying user defined variables
Variables are immutable, but you can redefine a variable in the current scope based of the old value of the variable like follows
Variable indexers
When modifying/defining variables, you can use the same indexers that you can with fields
Remember though, variables are immutable, so even though its "setting" the value to 5 or "doubling" every value, it's actually creating a completely new object to replace the variable pointed to by $x
Expressions
Now that you have learned how to express and store/access data, the last thing you need to learn is how to modify data and combine it with other pieces of data. The way to do this, is expressions, which are essentially a sequence of operations that can be done on data, like the mathematical concept of an expression. The individual components that describe the actions being done are called operators, and the expressions being used with these operators are called operands.
Values and Variables as expressions
With the foreword out of the way, the simplest type of expression has already been described, values and variable references.
Unary Prefix Operators
There are 3 unary prefix expressions: not
, +
, and -
, a unary prefix operator means that the operator is placed directly to the left of the expression that it is being operated upon, example being -$something
+
This operator actually is the equivalent of doing nothing, it multiplies its operand by +1
Example:
-
This operator multiplies its operand by -1
Example:
not
This operator returns false
if its operand resolves to a value being truthy, otherwise it returns true
.
Example:
Binary Numeric Operators
Binary numeric operators, are operators that usually (but not always) operate on numbers, and are placed as an infix between the 2 expressions making up their operand
+
This operator results in the value of its 2 operands added together, when used on operands that are numbers (integer
/real
), and if either operand is a real
it will return a real
otherwise it returns an integer
This operator can also have different results depending on the other operands it has. These results are defined in the following sections, any combination not described will throw an error.
string + string
If the operands to +
are strings, then this will concatenate the 2 strings, that is put them together end to end creating a new string.
list + list
If the operands to +
are lists, then this will append all values of the righthand list to the lefthand list creating a new list.
-
This operator results in the value of its right hand operand subtracted from the value of its left hand operand, when used on operands that are numbers (integer
/real
), and if either operand is a real
it will return a real
otherwise it returns an integer
.
When used on any other data types, it will throw an error.
*
This operator results in the value of its 2 operands multiplied, when used on operands that are numbers (integer
/real
), and if either operand is a real
it will return a real
otherwise it returns an integer
.
This operator can also have different results depending on the other operands it has. These results are defined in the following sections, any combination not described will throw an error.
string * integer and integer * string
When you use the *
operator to multiply a string and an integer or vice versa, the result is the string repeated by an amount that is the value of the integer.
list * integer and integer * list
Similar to the above, the result of multiplying a string and a list is the list repeated by an amount that is the value of the integer.
/
This operator results in the value of its left hand operand divided by the value of its right hand operand, when used on operands that are numbers (integer
/real
), and if either operand is a real
it will return a real
otherwise it returns an integer
.
When used on any other data types, it will throw an error.
%
This operator results in the the remainder of the division of the value of its left hand by the value of its right hand operand when used on operands that are numbers (integer
/real
), and if either operand is a real
it will return a real
otherwise it returns an integer
.
When used on any other data types, it will throw an error.
Binary Equality Operators
Binary equality operators are used to compare the equality of 2 values, and there are 2 of them ==
and !=
, they can be used on values of any type, but both sides must be the same type or the values will be considered to not be equal.
When used on lists it compares member wise if each value is equal, and when on dictionaries, it compares if they have the same keys, and then keywise if each value is equal.
==
will return true when the operands are equal, and otherwise false
!=
will return false when the operands are equal, and otherwise true
A few examples of this behaviour are as follows:
Binary Relational Operators
Binary relational operators are operators only used on the numeric types that compare the relations of the numbers, there are four relation operators that do the following things
- <
results in true if the left operand's value is less than that of the right operand's value
example:
5 < 3
results in false, while3 < 5
results in true- <=
results in true if the left operand's value is less than or equal to that of the right operand's value
example:
4 <= 5
and5 <= 5
both result in true, while5 <= 4
results in false- >
results in true if the left operand's value is greater than that of the right operand's value
example:
5 > 3
results in true, while3 > 5
results in false- >=
results in true if the left operand's value is greater than or equal to that of the right operand's value
example:
5 >= 4
and5 >= 5
both result in true, while4 >= 5
results in false
Binary Boolean Operators
Binary boolean operators are operators that operate on the truthiness of their operands, there are 2 of these operators
- and
this operator results in true if both of its operands are truthy, otherwise false, it short circuits such that if the first operand results in a falsy value, it doesn't evaluate the second operand
example:
(1 > 2) and true
results in false, while(1 < 2) and (1 == 1)
results in true- or
this operator results in true if either of its operands are truthy, otherwise false, it short circuits such that if the first operand results in a truthy value, it doesn't evaluate the second operand
example:
(1 > 2) or true
results in true, while(1 > 2) or (5 <= 4)
results in false
Subscript Operator
The subscript operator is how you get individual values from maps and lists, it is a [...]
postfixed after the map/list you want to retrieve a value from, with the ...
replaced by the index, which for lists is any expression that results in a number that is at least zero, as lists are zero indexed (meaning 0
is the first index in a list), and for maps, its any expression that results in a string, that becomes the key you want to retrieve a value from. For a few examples:
Ternary Operator
The ternary operator is a special 3 operand operator that looks like this [a] @if [condition] @else [b]
, where it will evaluate the truthiness of [condition]
and if it is truthy it will evaluate and result in [a]
otherwise it will evaluate and result in [b]
. Or for a better example:
Other Operators
There are a few other operators not described here that are described within the advanced Functions and Closures page.
Combining Expressions
As you may have picked up from the previous sections, you can combine expressions using the operands, and you may have noticed that in some places parentheses are being used to wrap the expressions. This is because of operator precedence. Where the operators higher up on the list of precedence more tightly group than those below, like *
more tightly groups than +
, so in the case of 5 + 3 * 4
, this is interpreted as 5 + (3*4)
rather than (5+3)*4
, as such you can use parentheses to change how precedence works. The list of precedence from the highest precedence to the lowest precedence is as follows:
Values/Variables
()
Unary Prefix
-
Unary Prefix
+
Unary Prefix
not
Simple function call (described in Functions and Closures)
Member function call (described in Functions and Closures)
[]
subscript*
/
%
+
-
>
<
>=
<=
==
!=
and
or
@if
/@else
What next
With the conclusion of this page, you have completed the basic syntax tutorials, and can either start with the Part Patching Tutorials, or continue with learning the syntax under the intermediate section of the General Syntax Tutorials.