Persistence in the Oberon system is obtained by a persistent heap on the disk. Persistent objects are on this heap, while transient objects are in the transient memory. Transient and persistent objects can access each other mutually. Accessing a persistent object leads to loading the object into the transient heap. If they are not accessed from transient objects any more, they will be written back to the persistent heap. Persistent objects, which are not referenced by other persistent objects, are reclaimed by a garbage collector.
One major design goal, has been that manipulating persistent objects should work like manipulating transient objects, i.e., no specific NEW statement and no explicit IO should be necessary.Therefore we chose the following mechanism: An object is persistent if it can be reached from a persistent root. Every object may become a persistent root if it is registered with the function Persistent.SetRoot (obj, key), where obj is (a pointer to) an object and key is a user-defined unique alpha-numerical key. If not defined otherwise, all objects referenced directly or indirectly by a persistent root are automatically persistent as well.
Applications may access a root object with the name key by using the function Persistent.GetRoot (obj, key). Having the root, persistent objects which are directly or indirectly referenced from the respective root object can simply be accessed by pointer dereferencing.
The code fragement MakeStringPersistent shows how to make a string object identified by the key myroot persistent. How to access this string object afterwards is depicted in the code fragement AccessAndPrintString.
PROCEDURE MakeStringPersistent; VAR s: POINTER TO ARRAY OF CHAR; BEGIN NEW (s, 32); s := "Oberon-D"; Persistent.SetRoot (s, "myroot") END MakeStringPersistent; PROCEDURE AccessAndPrintString; VAR s: POINTER TO ARRAY OF CHAR; BEGIN Persistent.GetRoot (s, "myroot"); Out.String (s^) END AccessAndPrintString;
Another example can be seen here.