[ Team LiB ] |
10.2 TargetAt every moment in AppleScript code, you are speaking to some object. That object is the target, to which, unless you specify otherwise, all messages will be sent. The target can be implicit, or you can specify an explicit target. Knowing what object is the target, and how to specify a desired target, is very important to your successful use of AppleScript. The implicit target is the current script or script object. In this code, the implicit target of set is the script itself: set x to 5 In this code, the implicit target of set is the script object myScript: script myScript set x to 5 end script There are two ways to specify an explicit target. Not coincidentally, they bear a strong resemblance to the two ways of accessing a script object's top-level entities (Chapter 9). You can specify an explicit target:
Here's an example of a tell block used to specify a target: tell application "Finder" count folders end tell Here's the single-line version of that code: tell application "Finder" to count folders Both the count command and the word folders are within the context of a tell block directed at the Finder. Thus the count message will be sent to the Finder, and the Finder's folders will be counted. (The tell block also makes a difference as to what the word folders means; it is the Finder that extends the AppleScript language to include this word. This, however, is a separate matter from the target. We'll come back to this matter under Section 12.3 in Chapter 12, and in Chapter 19.) Here's an example of the of operator being used to specify a target: using terms from application "Finder" count folders of application "Finder" end using terms from Thanks to the of operator, the Finder is the target of the count command; it will be sent the count message, and its folders will be counted. (The using terms from block, which I refer to in this book as a "terms block," is present to allow the term folders to be interpreted correctly. This is also explained in Chapter 12 and Chapter 19.) 10.2.1 The Chain of Ofs and TellsObjects, as we shall see in more detail later in this chapter, may be attributes of one another. It is actually this relationship that is specified with the of operator. That is why you can speak of a property myProp of a script object myScript like this: get myProp of myScript The top-level entities of a script object, including its script properties, are attributes of that script object. This relationship can be extended. For example, perhaps myScript contains a top-level definition for a script object myInnerScript that has a script property called myInnerProp; then you can say this: get myInnerProp of myInnerScript of myScript Thus we end up with a chain of ofs that is used to determine the target. Since both tell and of perform the same function of determining the target, there is a sense in which tell and of are interchangeable. Thus it is possible to replace the chain of ofs by a chain of tells in the opposite order. This code is effectively identical to the previous example: tell myScript tell its myInnerScript get its myInnerProp end tell end tell In determining the target, AppleScript actually works its way up the chain of ofs and then up the chain of tells until it assembles a complete target. (I am deliberately waving my hands over what I mean by "a complete target," but it means something like an application, a script, or a value within your script.) Thus it makes no difference whether you say this: tell application "Finder" count folders of folder 1 end tell or this: tell application "Finder" tell folder 1 count folders end tell end tell It is also perfectly possible for the of operator to appear in the announcement line of a tell block. It makes no difference whether you say this: tell application "Finder" tell folder 1 tell file 1 get name end tell end tell end tell or this: tell application "Finder" tell file 1 of folder 1 get name end tell end tell See Chapter 3 for an extensive practical demonstration of the interchangeability of of with tell throughout the chain. 10.2.2 Multiple AssignmentsRecall from Chapter 7 that it is possible to assign multiple values in a single command by using a list: set {x, y, z} to {1, 2, 3} You can use this syntax to fetch multiple properties, using either tell or of: tell application "Finder" set {x, y} to {name, comment} of folder 1 end tell {x, y} -- {"Mannie", "howdy"} That code fetches name of folder 1 and comment of folder 1 from the Finder in a single command. You can use this construct to set multiple properties as well, but only in a tell block (trying to do it with of will cause a runtime error): tell application "Finder" tell folder "Mannie" set {comment, name} to {"zowie", "Jack"} end tell end tell Be careful of the order in which you list the properties when assigning to them. The values are assigned from left to right. This wouldn't have worked: tell application "Finder" tell folder "Mannie" set {name, comment} to {"Jack", "zowie"} -- error end tell end tell That would have set the name first, and afterwards there would no longer be a folder "Mannie" to set the comment of, so the attempt to set the comment of folder "Mannie" would have caused a runtime error. 10.2.3 Nesting Target SpecificationsOnce AppleScript has determined a complete target, it stops, ignoring any further ofs or tells that make up the rest of the chain. Consider, for example, the following: tell application "Mailsmith" tell application "Finder" count folders end tell end tell Mailsmith is not in fact targeted in any way here; no message will be sent to it when the code runs. AppleScript works its way outwards from the count command until it reaches the Finder; now AppleScript has assembled a complete target, and stops. In fact, if you try to write the same thing this way: count folders of application "Finder" of application "Mailsmith" AppleScript literally throws away the mention of Mailsmith after compilation: count folders of application "Finder" 10.2.4 Direct ObjectMost commands have a direct object, which can be expressed right after the verb. Using of, you may include as much as you like of the target as the direct object of a command—all of it, none of it, or anything in between. Whatever you don't include in the direct object you can put in a tell. So, in this example, the entire target appears as the direct object of the command: using terms from application "Finder" count folders of application "Finder" end using terms from In this example, some of the target appears as the direct object, and some of it appears in a tell: tell application "Finder" count folders end tell And here, the whole target appears in a nest of tells, and none of it appears as the direct object of the command: tell application "Finder" tell folders count end tell end tell The keyword it represents the target. (See Section 10.4, later in this chapter.) You can include it as the direct object of the command if it doesn't otherwise have one, but this changes nothing: tell application "Finder" tell folders count it end tell end tell Nothing stops you from putting something else as the direct object of the command—something that retargets it. For example: tell application "Finder" tell folders count words of "hi there" end tell end tell In that code, no message is sent to the Finder! The phrase words of "hi there" is a complete target (a value). The tell blocks are ignored for purposes of this command. Usually, you may use the word of to connect a command with its direct object. So you could say this: tell application "Finder" count of folders end tell This usage of of is related to the special of that can mark the first parameter when using prepositional parameters in a handler call (Chapter 8). The apostrophe-ess operator is not a synonym for this usage. 10.2.5 Names in ScopeThe rules for targeting do not override the scoping rules you have learned in the previous three chapters. You can say this: set x to 10 tell application "Finder" get x end tell AppleScript knows that x is something meaningful in the context of the script itself, so it doesn't send any message to the Finder asking about x. That's a good thing, because the Finder doesn't know about anything called x. This is a thoroughly necessary mechanism, since without it a tell block would cut off access to the surrounding context and you wouldn't be able to use names that are in scope while explicitly targeting something. You can therefore quite freely mingle names defined in the current context with names defined by the target. AppleScript is able to deal very nicely with this code: set L to {"Mannie", "Moe", "Jack"} tell application "Finder" count folders count L end tell The command count folders is sent to the Finder. The command count L is not; AppleScript knows that L is something belonging to the current context, not to the Finder, and the command is dealt with entirely within the script. Here's another example with even more mingling: set newname to "someFolder" tell application "Finder" set oldname to name of folder 1 set name of folder 1 to newname end tell display dialog oldname In that example, folder and name are part of messages sent to the Finder, but oldname and newname are (implicit) globals within the script, and their values are set and retrieved without involving the Finder. In this line: set oldname to name of folder 1 AppleScript actually does two things; first it sends this message to the Finder (see Section 10.3): get name of folder 1 Then it uses the result to set the value of oldname. The mental picture I want you to have is one involving a clear division of labor: the Finder is sent messages telling it to do things involving the Finder, and the script is sent messages telling it to do things involving the script. The Finder does not somehow lay hands on any of your script's variables. Thus, when it comes to terms you use that might be the names of entities in scope in your script, AppleScript must look in two places to resolve their meaning: in the targeted application, and in the script itself. This mechanism is actually quite subtle, and is discussed further in Section 19.1. Do keep in mind that handler calls are special. A handler call is a message and will be sent to the target. This won't work: on whatNumber( ) return 1 end whatNumber tell application "Finder" get folder whatNumber( ) -- error end tell The problem is that the Finder is sent the whatNumber message, but it knows of no whatNumber command. We'll see how to get around this later in the chapter (Section 10.5). |
[ Team LiB ] |