AppleScript_ The Definitive Guide - Matt Neuburg [75]
end script
mommy's tellWeight( ) -- 120 pounds
baby's tellWeight( ) -- 9 pounds
baby2's tellWeight( ) -- 8 pounds
In that example, the parental phrase my weight gets three different interpretations, depending solely on what script object was targeted originally.
Again, there is no need to use my (or its) with a handler call; polymorphism operates automatically, as this example shows:
script mommy
on cry( )
display dialog "Boo-hoo, sniff sniff..."
end cry
on beSad( )
cry( )
end beSad
end script
script baby
property parent : mommy
on cry( )
display dialog "Waaaaaaa!"
end cry
end script
baby's beSad( ) -- Waaaaaaa!
It's mommy that implements beSad, but the original target was baby, so it's baby's cry that is called.
Continue
A child can call an inherited handler by using the continue command. The syntax is the keyword continue followed by a complete handler call (parameters and all).
You might wonder why this is needed, as after all the child can just send a message directly to the parent. It could do this, for instance, by referring to the parent as parent. But there's a crucial difference. If a message is sent to the parent by referring to it as parent, that's a new message with a new target. On the other hand, the continue command takes place in the context of the current message and the current target; it passes the current flow of control up the inheritance chain. Thus, the one breaks polymorphism, the other does not.
This example demonstrates the difference:
script mommy
property weight : "120 pounds"
on tellWeight( )
display dialog my weight
end tellWeight
end script
script baby
property parent : mommy
property weight : "9 pounds"
parent's tellWeight( ) -- no polymorphism
continue tellWeight( ) -- polymorphism
end script
run baby -- 120 pounds, 9 pounds
The Implicit Parent Chain
A script object without an explicitly specified parent has as its parent the script as a whole. That fact is surprising and is worth stressing. Mere physical nesting is not implicit parenthood:
script myScript
script myInnerScript
my parent -- the top-level script, not myScript
end script
run myInnerScript
end script
run myScript
Nor, indeed, can a nested script object be made to have a containing script object as its parent. AppleScript will balk if you try this:
script myScript
script myInnerScript
property parent: myScript -- compile-time error
end script
end script
(I think the reason for this restriction must be that the demands of parenthood would conflict irresolvably with the rules of scoping.)
The implicit parent chain explains why certain things work that look like they shouldn't work. Here's an example:
property x : 10
script outer
property x : 20
script inner
end script
end script
get outer's inner's x -- 10
If you go by your intuitions alone, you might think the search for x starts in inner and works its way up the nest. We come immediately to x in outer. So the result of the script should be 20. Your intuitions are wrong. They are right for how scope works (see Chapter 10), but this isn't about scope; it's about accessing top-level entities. Top-level entities are sought up the parent chain, and the top-level script, not outer, is inner's parent. Similarly:
on sayHowdy( )
display dialog "Howdy"
end sayHowdy
script s
end script
tell s to sayHowdy( ) -- Howdy
That works not because s can "see" sayHowdy but because sayHowdy is a top-level entity of s's parent. If you don't believe me, I can prove it by breaking the inheritance chain. This isn't easy, because if I set s's parent to a different script object, the script itself will be the parent of that script object, and we'll get the same result. So I'll set s's parent to something that isn't a script object:
on sayHowdy( )
display dialog "Howdy"
end sayHowdy
script s
property parent : 3
end script
tell s to sayHowdy( ) -- Error: Can't get sayHowdy of 3
We can take advantage of the inheritance chain to refer to a top-level entity of the script itself, even though