Method code for $root.change_parents()

[Turn on line numbering]
arg parents;
var old_a, old_p, a, obj, new_a, definer, branch, method, str;

if (!parents)
    throw(~noparents, "Objects must have at least 1 parent");

// remember a few things
old_a = setremove(ancestors(), this());
old_p = .parents();
branch = .descendants() + [this()];

// build the new ancestors list by hand, so we can figure out what is
// changing, and uninitialize those ancestors that are going away
new_a = [];
for obj in (parents)
    new_a = union(new_a, obj.ancestors());

// uninit any ancestors going away
for a in (old_a.set_difference(new_a)) {
    // call this ancestor's uninit on the obj and all its children
    method = tosym("uninit_" + a.objname());
    if ((definer = (| find_method(method) |))) {
        if (definer != a) {
            // scream madly and run around--everybody should know this
            str = "UNINIT ERROR: uninit method for " + a;
            str += " in wrong place (" + definer + ")";
            (| definer.manager().tell(str) |);
            (| a.manager().tell(str) |);
            (| sender().tell(str) |);
            continue;
        }

        // call the uninit method on this object only
        catch any {
            .(method)();
        } with {
            // try and let somebody know they made a boo-boo somewhere
            str = "UNINIT ERROR " + obj + "<" + this() + ">:";
            (| .manager().tell(str) |);
            (| .manager().tell_traceback(traceback()) |);
            (| sender().tell(str) |);
            (| sender().tell_traceback(traceback()) |);
            (| sender().tell("Continuing chparent..") |);
        }
    }

    // cleanup any old obj vars left lying around
    // if (branch)
    //     $sys.clear_definer_vars(a, branch);
    $sys.clear_definer_vars(a, [this()]);
    refresh();
}

// make the change
(> chparents(parents) <);
if ('core in .flags())
    $changelog.log("CHANGE-PARENTS: " + this() + " from " + old_p + " to " + parents() + " by ");
new_a = setremove(ancestors(), this());

// init anybody new to the family
for a in (new_a.set_difference(old_a)) {
    method = tosym("init_" + a.objname());
    if ((definer = (| find_method(method) |))) {
        if (definer != a) {
            // scream madly and run around--everybody should know this
            // (damn inlaws, can't ever get things right)
            str = "INIT ERROR: init method for " + a;
            str += " in wrong place (" + definer + ")";
            (| definer.manager().tell(str) |);
            (| a.manager().tell(str) |);
            (| sender().tell(str) |);
            continue;
        }

        // introduce the new ancestor
        catch any {
            .(method)();
        } with {
            // try and let somebody know they made a boo-boo somewhere
            str = "INIT ERROR " + obj + "<" + this() + ">:";
            (| .manager().tell(str) |);
            (| .manager().tell_traceback(traceback()) |);
            (| sender().tell(str) |);
            (| sender().tell_traceback(traceback()) |);
            (| sender().tell("Continuing chparent..") |);
        }
    }
    refresh();
}

// $#Edited: 24 Jul 97 04:27 $brandon
// $#Edited: 28 Sep 98 05:22 $brandon
// $#Edited: 18 Jul 99 13:31 $brandon
// $#Edited: 20 Jan 02 22:43 $brandon

["// Created as a part of ColdCore, see: @help Credit"]

the Cold Dark