In Director, an ancestor is just another birthed object that you link to your own. If your object receives a message that it doesn't have a handler for, it passes the message along to its ancestor object to see if that has a handler for it, much as a mouseClick that doesn't get handled by a sprite script will be passed along to the relevant cast script.
In order to attach an ancestor to an object, you must birth an object from the ancestor script (exactly as you would from any parent script), and then put that object into a property variable called "ancestor". For example :
-- this script is called "ma"
property ancestor
on birth me
set the ancestor of me = birth( script "grandma" )
return me
end birth
What does this do when it receives a "birth" message?
First of all, it births an object from another script called "grandma". This works just the same as any birthing process. Then, it looks for the property variable "ancestor" in "me", and assigns the created object to that. Having satisfactorily initialized itself, it then passes "me" back to the script that originally made the birth() call. (Note that, since it isn't explicitly returned, the "grandma" object would normally get vaped as soon as the handler came to an end. However, because we've put it into a property variable, it persists for the life of the "ma" object.)
All fine and dandy, but what's the point? Well, this parent script doesn't really do anything: it has no handlers and no user-defined properties, and in fact it's pretty useless all round. But imagine that "grandma" creates a fantastically useful object with dozens of handlers. The object birthed by "ma", because it includes this object, immediately inherits all of those handlers.
So, if one of "grandma"'s handlers is:
on bleep me
beep 3
end bleep
And you do the following:
put birth(script "ma") into mommy
bleep mommy
there'll be three beeps, even though the script for "ma" doesn't contain
any such handler.
Okay, you're saying to yourself, why bother with "ma" at all? Why not just go straight to "grandma"? In this case, there's no reason at all: "ma" doesn't add anything to grandma, so there's no point. But suppose you wanted to create a bunch of objects exactly like "grandma", with all her bells and whistles, but which beep *four* times in response to a "bleep" message, rather than the usual three. If you add this to "ma" :
on bleep me
beep 4
end bleep
then objects birthed from "ma" will do just that: they inherit all the rest
of their behaviour from the fabulous "grandma", but conveniently intercept
"bleep" messages to make four beeps rather than three.
What all this means is that you can start off with a single parent script containing all the basic handlers that all your objects are going to use, and then create various customized versions of it, all sharing the same basic structure but adding or changing their behaviour as necessary. Each parent script only needs to handle the stuff that differs from the ancestral defaults, and can just inherit all the rest.
There's a couple of other things worth noting about ancestors. The first, which is a bit obvious, is that it's not a good idea to do this :
-- in script "blah"
on birth me
put birth(script "blah") into ancestor
end birth
Each time you birth an object from this script, it births another, which
births another and so on until there are blahs all over the place like
tribbles, and Director falls over.
It
ispossible to make an object's ancestor another object birthed from the same script, but I don't think you'll find a good reason for doing so. The only use that springs to mind is to implement some kind of list or tree structure, and since Director already gives you much more efficient list handling tools, this is a pointless thing to do.
The second thing, not as immediately obvious, is that since the properties of a child object in Director can be tested and set from outside the object, you can reassign the ancestry of an existing object on the fly :
put birth(script "blah") into aBlah put birth(script "wotsit") into aWotsit set the ancestor of aWotsit = aBlahYou could, for example, have two objects sharing a single other object as their common ancestor (ie, both modifying the same set of property variables). This sort of thing should be done with great care. Remember that sending a message to an object that doesn't have a handler for it will cause your movie to halt with a script error alert. Always make sure that when your objects *expect* to have particular handlers in their ancestry, those handlers are actually there!