[Turn off line numbering]1: arg parents; 2: var old_a, old_p, a, obj, new_a, definer, branch, method, str; 3: 4: if (!parents) 5: throw(~noparents, "Objects must have at least 1 parent"); 6: 7: // remember a few things 8: old_a = setremove(ancestors(), this()); 9: old_p = .parents(); 10: branch = .descendants() + [this()]; 11: 12: // build the new ancestors list by hand, so we can figure out what is 13: // changing, and uninitialize those ancestors that are going away 14: new_a = []; 15: for obj in (parents) 16: new_a = union(new_a, obj.ancestors()); 17: 18: // uninit any ancestors going away 19: for a in (old_a.set_difference(new_a)) { 20: // call this ancestor's uninit on the obj and all its children 21: method = tosym("uninit_" + a.objname()); 22: if ((definer = (| find_method(method) |))) { 23: if (definer != a) { 24: // scream madly and run around--everybody should know this 25: str = "UNINIT ERROR: uninit method for " + a; 26: str += " in wrong place (" + definer + ")"; 27: (| definer.manager().tell(str) |); 28: (| a.manager().tell(str) |); 29: (| sender().tell(str) |); 30: continue; 31: } 32: 33: // call the uninit method on this object only 34: catch any { 35: .(method)(); 36: } with { 37: // try and let somebody know they made a boo-boo somewhere 38: str = "UNINIT ERROR " + obj + "<" + this() + ">:"; 39: (| .manager().tell(str) |); 40: (| .manager().tell_traceback(traceback()) |); 41: (| sender().tell(str) |); 42: (| sender().tell_traceback(traceback()) |); 43: (| sender().tell("Continuing chparent..") |); 44: } 45: } 46: 47: // cleanup any old obj vars left lying around 48: // if (branch) 49: // $sys.clear_definer_vars(a, branch); 50: $sys.clear_definer_vars(a, [this()]); 51: refresh(); 52: } 53: 54: // make the change 55: (> chparents(parents) <); 56: if ('core in .flags()) 57: $changelog.log("CHANGE-PARENTS: " + this() + " from " + old_p + " to " + parents() + " by "); 58: new_a = setremove(ancestors(), this()); 59: 60: // init anybody new to the family 61: for a in (new_a.set_difference(old_a)) { 62: method = tosym("init_" + a.objname()); 63: if ((definer = (| find_method(method) |))) { 64: if (definer != a) { 65: // scream madly and run around--everybody should know this 66: // (damn inlaws, can't ever get things right) 67: str = "INIT ERROR: init method for " + a; 68: str += " in wrong place (" + definer + ")"; 69: (| definer.manager().tell(str) |); 70: (| a.manager().tell(str) |); 71: (| sender().tell(str) |); 72: continue; 73: } 74: 75: // introduce the new ancestor 76: catch any { 77: .(method)(); 78: } with { 79: // try and let somebody know they made a boo-boo somewhere 80: str = "INIT ERROR " + obj + "<" + this() + ">:"; 81: (| .manager().tell(str) |); 82: (| .manager().tell_traceback(traceback()) |); 83: (| sender().tell(str) |); 84: (| sender().tell_traceback(traceback()) |); 85: (| sender().tell("Continuing chparent..") |); 86: } 87: } 88: refresh(); 89: }
// Created as a part of ColdCore, see: @help Credit