Menu

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().)