Online Book Reader

Home Category

AppleScript_ The Definitive Guide - Matt Neuburg [77]

By Root 1384 0
its, AppleScript doesn't know you're talking about s's property p. It thinks you must be talking about some other p, and there isn't one.

This is true for a handler too, if we simply treat the handler as the value of a variable:

script s

on h( )

return 10

end h

end script

tell s

get h

end tell

Again, we get an error that h is undefined.

But a handler call is different. This works without its:

script s

on h( )

return 10

end h

end script

tell s

h( ) -- 10

end tell

So a handler call is automatically treated as an attempt to access a top-level entity. It's important to stay conscious of this, because if you go by your intuitions alone you may be confused. Consider this script:

script x

property greeting : "Howdy"

on myHandler( )

display dialog greeting

end myHandler

script y

display dialog greeting

myHandler( )

end script

end script

run x's y -- Howdy, then error: «script y» doesn't understand the myHandler message

It looks like the property greeting and the handler myHandler are in the same place, so they should have the same status. And that's true, as far as it goes. But y apparently can see greeting, yet it fails in its attempt to call myHandler. That is also true. The reason is that a handler call is not the same thing as just saying the name of some variable. A handler call is routed as a search for a top-level entity. The search starts in y. myHandler isn't there, so we pass to the parent. The parent isn't x; it's the top-level script. myHandler isn't there either. So the search fails. This is not to say that you can never call myHandler at all. You simply have to target x explicitly when you do:

script x

property greeting : "Howdy"

on myHandler( )

display dialog greeting

end myHandler

script y

x's myHandler( ) -- explicit target

end script

end script

run x's y -- Howdy

I think the reason for this special status of a handler call is that AppleScript wants to treat a handler call as a command. Its status is like that of the built-in commands, such as run and count. When you give a command to a script object, you don't want to have to talk in some special way; you are sending a message and you want that message to go to the right place all by itself. So a handler call works that way too.

To see that this probably the right sort of explanation, consider how the message-passing mechanism works when you send a built-in command to a script object:

script s

end script

tell s to count -- 0

The count message is routed just the way a handler call is routed. If a script object implements count, it is this count that is called:

script theCount

on count

return "1, 2, 3, ha ha ha"

end count

end script

tell theCount to count -- "1, 2, 3, ha ha ha"

Alternatively, if we give s a parent that implements count in a different way, then the count command is routed to that parent:

script s

property parent : {"Mannie", "Moe", "Jack"}

end script

tell s to count -- 3

(We'll return to weird handlers like count in Chapter 9, and to objects and the message-sending mechanism in Chapter 11.)

So it appears that the inheritance chain is involved in every command. Whether it's a handler call or a built-in command, it has some target and is passed up the inheritance chain from that target until we come to someone who can obey. This probably also explains the curious language of the error message you get when you misdirect a handler call to a scriptable application:

tell application "Finder"

sayHowdy( ) -- Finder got an error: Can't continue sayHowdy.

end tell

It's as if the Finder were a sort of script object, saying, "I don't know what this command means, and I haven't got a parent to pass it along to."

Because handler calls and commands are passed up the inheritance chain, the current application is the implicit target of every command not otherwise targeted. This fact is rarely useful, though. For example, in theory, if a script that drives BBEdit is to run in BBEdit's Script menu, it doesn't need to target BBEdit in a tell block; BBEdit is the current application, so

Return Main Page Previous Page Next Page

®Online Book Reader