RecursivelyNIL.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Bob Hagmann, May 20, 1985 8:31:06 am PDT
NILRef will take a REF ANY to a structure, and recursively processes all objects within the structure and NIL out all REFs inside any reachable object. This is useful for programs that build a complicated data structure, and now are "done" with it.
RecursivelyNIL will not go inside finalizable objects (those objects for which SafeStorage.EnableFinalization has been called): it will NIL out references to them, but will not go inside the "package data structure" and destroy it. This helps prevent a "ZCT Disaster". In addition, it will not process inside of ROPEs. NILRef has optional checkProc argument. If not specified, defaults to a procedure that returns TRUE. Otherwise, for every object found and ref inside the object, your CheckProc is called to see if it is OK to NIL out the REF. This allows you to customize the program to avoid NIL of certain types of objects. If you return OKToNIL as TRUE, the field will be NILed and the field will not be followed in the recursive process.
Seven star warning: NILRef really will nil out everything that it reachable from the root. In particular, if it can get to any viewer, it will destroy everything on the screen!
Safety and concurrency: NILRef is supposed to be safe, but there should be no concurrent updates in the structure that it is destroying. I think that it will not violate safety, but may have strange looping behavior if its data structure is changing.
DIRECTORY
SafeStorage USING[Type];
RecursivelyNIL: DEFINITIONS
= BEGIN
CheckProc: TYPE = PROC [objectREF: REF ANY, objectREFType: SafeStorage.Type, referredREF: REF ANY, referredREFType: SafeStorage.Type] RETURNS [OKToNIL: BOOL ← TRUE];
NILRef: PROC[root: REF ANY, checkProc: CheckProc ← NIL];
END.