MAXScript uses a type of assignment called reference assignment. When you create a value, for example, by writing a literal, the memory for that value is allocated and a pointer or reference to the value is placed into the variable rather than the value itself. If you assign that variable's value to another variable, the reference to that value's memory is placed in the new variable. The same applies to assigning a variable’s value to an array element or passing it as a function call argument. In all cases, the reference is assigned or passed. When you assign a new value to a variable or when a variable goes out of scope, the reference that the variable contained is dropped. When your program has dropped all references to a value's memory, that memory becomes eligible for reclamation.
This is in contrast to value assignment in which a copy of the whole value's memory is made and assigned. Value assignment has one advantage over reference assignment; every time a variable or an array element is re-assigned, the old value’s memory space can be immediately reclaimed because the old value is unique and nothing else can be referring to it. With reference assignment, the system cannot reclaim the original value’s memory space because other variables might still point to the same value.
Some scripting languages use a copy-based approach such as, HyperCard's HyperTalk, but its inefficiency as well as some value sharing problems make it inappropriate for MAXScript. This creates the task of reclaiming memory in MAXScript. Programming languages such as, C or Pascal require that the programmer explicitly reclaim a value's memory when it is no longer needed, and this is one of the most difficult parts of programming in those languages. Recent variants like Java and some advanced languages like Lisp and Smalltalk provide automatic memory reclamation. MAXScript also provides this and it is described in Memory Allocation and Garbage Collection.
If you assign a variable's value to another variable, the reference to that value's memory is placed in the new variable. Thus, both variables are actually referencing the same value. If you assign a new value to one of the variables, the variable will contain a reference to the new value and the other variable will contain a reference to the old value. Normally this is the desired behavior as you do not want both variables to reference the new value. However, a complication occurs if a compound value like a point3 or array is referenced by more than one variable, and you assign a new value to a component of the compound value. When you assign a value to a component of the compound value, a new compound value is not created. Therefore, any variables that reference the compound value will still point to the same value, and will "see" the changed component value. Examples of this behavior are shown in the following script:
SCRIPT
( a= "hello world" -- create a string value, put reference in a b=a -- put string’s reference in b format "a=%; b=%\n" a b -- and print their values b= "thanks for the fish" -- create a string value, put reference in b format "a=%; b=%\n" a b -- print values - they are different b=a -- put string’s reference from a in b a[1]= "J" -- change a component value format "a=%; b=%\n" a b -- print values - they are the same a=b=[10,20,30] -- assign a point3 value reference to a and b format "a=%; b=%\n" a b -- and print their values a.x=-100 -- change a component value format "a=%; b=%\n" a b -- print values - they are the same )
OUTPUT
a=hello world; b=hello world a=hello world; b=thanks for the fish a=Jello world; b=Jello world a=[10,20,30]; b=[10,20,30] a=[-100,20,30]; b=[-100,20,30] OK
In some cases, this behavior is the desired behavior, and in other cases it is not. For those cases where it is not the desired behavior, a copy()
method is defined for most value types that will create a separate copy of a value.
In some cases, such as, arrays and structures, the value might contain compound values. The copy made is called a shallow copy; only a copy of the upper-level value itself (that is, the array) is created. Copies are not made of compound values in the value (that is, the elements of the array).
In 3ds Max 9 and higher, a special copy method called deepCopy()
is available for copying arrays. It allows the copying of all compound values inside the array. See Array Values for details.