Block-expressions are the basic constructors for structured code. They allow you to group a sequence of expressions and evaluate them in sequence as though they were a single expression.
The syntax for <block_expr> is:
That is, a parenthesized sequence of expressions with each <expr> separated by either a line break or a "; " semicolon.
MAXScript also allows empty block-expressions, () . This is useful when incrementally building code in order to place an empty expression in a path to be filled in later. When evaluated, empty expressions yield the value undefined .
You can use a mixture of line breaks or semicolons:
Because a block-expression is an <operand> , you can insert a block-expression anywhere you can put an <operand>. This is unlike most languages which limit where you can put blocks of code to only a few places.
Further, because all constructs are expressions in MAXScript, a block-expression yields a value defined to be the last <expr> in the block. This allows you to use a nested sequence of expressions to compute an operand for some operation:
EXAMPLE: |
Here, the result of the block-expression is the result of the final if expression, which is then assigned to $box.pos.z . |
Because the item in parentheses can be any<expr>, you can turn any construct in MAXScript into an operand by putting it in parentheses. This allows you to write the following example, in which the operand to be indexed is the conditional result of an if expression:
As described in Scope of Variables, top-level open parentheses in a script file or in the Listener create a new variable scope. Any block-expressions with the top-level block-expression do not create a new variable scope, even if the variable is explicitly declared as local in the inner block-expression. A variable’s scope extends into any block-expressions within the variable’s scope. If you declare a variable as local in a scope, the newly declared local variable hides any outer variables with the same name. Any reference to that variable name later in the local variable's scope refers to the new local variable. At the end of the local variable's scope, the next outer variable becomes visible again. This is shown in the following script:
Any variable names used in a block-expression which have not been created at a higher scope level are implicitly declared as local in the present scope. This can result in unexpected execution results for scripts that are not set up correctly.
When writing scripts, it is also a good programming practice to explicitly declare as local all variables unless you really want them to be global variables. There are several reasons for this practice:
All the variable names used in the block or function will be together, which makes it easier to find the variable names and helps prevent using incorrect names in the script.
If more than one script is executing at the same time (for example, you are running a scripted utility and have a scripted controller in the scene) and both scripts use the same global variable name, the two scripts can interfere with one another. This can cause apparently random failures of one or both scripts.
You are sure you are using the correct variable in the event that a variable with the same name has already been declared at a higher scope, and you won't inadvertently change the higher-level variable's value.
Values of variables explicitly defined as local are displayed in error call stack trace-backs.
In 3ds Max R2.5, if a 3ds Max class, a MAXScript method, or a MAXScript read-only global variable has the same name as an implicitly declared local variable, a MAXScript runtime error will be generated if an assignment to that variable name occurs. Since the variable name already existed with a global scope, an implicitly declared local variable was not created. Since one or more new 3ds Max classes will be created by any third party plug-ins the user has loaded, you were not be able to tell ahead of time if a variable name was a global variable name. In 3ds Max 4 and higher, if the MAXScript compiler detects that the first reference to such a variable is an assignment, it will implicitly declare a local variable, rather than leaving it as a reference to a read-only system global.