scScript Private Variables
scScript only provides local and global variables. But thanks to the magic of closures, local variables can persist outside their original scope. Better yet, multiple closures can have simultaneous private access to the same local variables, making them an otherwise hidden shared state or comm channel.
// Private Variable! (PV.sc) Var FuncA, FuncB;Var I;Function MakeFunc()() {Var PriVar = 1; FuncA =Function ()() Writeln("FuncA --> " , PriVar *= 2); FuncB =Function ()() Writeln("FuncB --> " , PriVar += 1); } MakeFunc();For (I = 0; I < 8; I++) {If (Sys.Rand() & 0x01) FuncA();Else FuncB(); }
In the above example two functions, FuncA
and FuncB, are defined within MakeFunc. When
MakeFunc is called in the script, it creates two closures
for them and assigns them to their respective named global variables.
But both closures capture PriVar, keeping the storage
location alive for a local variable that existed briefly only while
MakeFunc ran. So while FuncA
and FuncB remain, they trivially access the storage
location for PriVar. But no other code has access
to PriVar or its storage, as MakeFunc no
longer exists!
*Output* FuncA --> 2 FuncA --> 4 FuncB --> 5 FuncB --> 6 FuncA --> 12 FuncA --> 24 FuncB --> 25 FuncA --> 50 ********************************************* SCRIPT RETURN --> 0 *********************************************
If the variables for FuncA and FuncB get re-assigned, as in:
FuncA = FuncB = 0;
the two closures will be lost and the storage originally assigned to PriVar will (finally) be freed.
Non accessible storage will be freed immediately
if RefCounting is in effect (it can be turned off with a
compile flag). Otherwise, the system will free them when Mark/Sweep
GC is eventually called to clean up memory! (The user can explicitly
invoke Mark/Sweep GC with Sys.GC().)