Previous Page
Next Page

11.4. Target

At every moment in AppleScript code, you are speaking to some object. That object is the target , to which all messages will be sent, unless you specify otherwise. 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. (See "Handler Calls, Commands, and Script Objects" in Chapter 8.) In this code, the implicit target is the script itself:

count

In this code, the implicit target is the script object myScript:

script myScript
    count
end script

There are three ways to specify an explicit target: as a direct object of a command , with a tell block, and with the of operator or one of its synonyms. These three ways may be combined to specify the complete target. (If they remind you of ways you can talk to a script object and access its top-level entities, they should; see Chapter 8.)

11.4.1. Direct Object

Most commands take at least one parameter. The unnamed parameter that directly follows the name of the command is the direct object. In the absence of any other target information, the target can occupy the place of the direct object.

In this example, we see the count message being sent to various targets, each of which interprets it in a different way:

script s
    on count
        return "1, 2, 3, ha ha ha"
    end count
end script
count s -- "1, 2, 3, ha ha ha"
count "hello" -- 5
count {1, 2, 3} -- 3
count application "Finder" -- 32 (the number of desktop items)

It is permitted to insert the word of between the command and the direct object (unless the command is get, set, or copy). It is also permitted to insert the word get before the command. This is rather confusing because it makes a command (such as count) look like an attribute, and I do not recommend talking this way.

count of "hello" -- 5
get count of "hello" -- 5
script s
    display dialog "howdy"
end script
get run of s -- howdy, but no one ever talks like this
get display dialog of "howdy" -- howdy (now stop that!)

This of is related to the special of that can mark the first parameter when using prepositional parameters in a handler call (see Chapter 9). The 's operator is not a synonym.

Don't confuse a command's direct object with the target. The target can occupy the direct object slot even if the command itself does not take a direct object. For example, the quit command has no direct object; it is sent to the target, and that is what quits.

quit application "Finder"

11.4.2. Tell Block

A tell block is a block introduced by the keyword tell. Immediately after that keyword comes the target. Commands within the block are directed to the target, unless they specify a different target. A tell block consisting of a single command can be written as a single line, using the syntax tell target to. Things I say about a tell block apply to this variant as well.

Here are some of the earlier direct object examples rewritten to use a tell block. They could all be rewritten in the same manner:

tell "hello"
    count -- 5
end tell
tell "hello" to count -- 5
tell application "Finder"
    count -- 32
end tell
tell application "Finder" to count -- 32

An important feature of a tell block is that it causes terminology within it to be resolved using the dictionary of the target application. Thus you can say things that would be illegal (without trickery) as a simple direct object.

sleep application "Finder" -- compile-time error, because the word "sleep"
 is not understood
tell application "Finder" to sleep -- snore...

The role of a tell block in resolution of terminology, and the trickery you can employ to resolve terminology without one, is discussed in detail in Chapters 19 and 20.

11.4.3. Of

Objects, as we have already seen, can have attributes. The only way, ultimately, to access an object's attributes is through some object that you can see directly. The way to express the relationship between the object that you can see directly and the attribute you want to access is with the of operator.

A synonym for of is in. (I never use this.) Another synonym, for most purposes, is the 's operator: instead of saying x of y, you can say y's x.

(Do not confuse the of operator here with the of that can optionally appear before the direct object of a command.)

The of operator can appear in a target specifier either in a direct object or in the announcement line of a tell block. For example:

open file 1 of application "Finder"
tell file 1 of application "Finder" to open
open application "Finder"'s file 1
tell application "Finder"'s file 1 to open

11.4.4. The Chain of Ofs and Tells

Material nested within a tell block is joined by an implicit of to the target specified in the announcement line of the tell block. (This device doesn't always work, and I'm being deliberately vague about some of the details; I'll provide them in "Get" and "It," later in this chapter.) So the previous example can be rewritten like this:

tell application "Finder"
    open file 1
end tell

This is in fact the canonical and most frequently used form. In the earlier forms, the entire target (with of) appears either after tell or after open. Here, the target is effectively divided into two: half of it appears in the announcement line in the tell block (application "Finder") and the other half appears as the direct object of the open command (file 1). Each half is a partial target . AppleScript joins them with of to form the complete target .

This form has two great advantages , explaining why it is the most frequently used:


Resolution of terminology

A tell block causes the terminology inside it to be resolved in accordance with the target application's dictionary. Thus you can say things in a tell block that you can say in no other way, because the terms you're using are not part of AppleScript itself and would cause a compile-time error outside a tell block.


Multiple commands to the same target

A tell block is a block, so it can contain more than one command. It is very frequently the case that you want to give more than one command to the same target or partial target, so a tell block is the most convenient construct. For example:

local n, c
tell application "Finder"
    tell folder 1
        tell file 1
            set n to name
            set c to comment
        end tell
    end tell
end tell

The chain of ofs needed to form a complete target is often longer than just two parts. In this case, you can divide the target into partial targets in whatever way is convenient: each part by itself in a nested tell block, or some parts joined together with of. These snippets all do the same thing:

tell application "Finder"
    tell folder 1
        tell file 1
            open
        end tell
    end tell
end tell
 
tell application "Finder"
    tell file 1 of folder 1
        open
    end tell
end tell
 
tell application "Finder"
    open file 1 of folder 1
end tell
 
tell application "Finder"
    tell folder 1
        open file 1
    end tell
end tell

(You'll notice that I didn't try to crowd any more of the target onto the first line; I didn't say tell folder 1 of application "Finder", for example. This expression is syntactically legal, but it won't compile, because the term folder is defined in the Finder's dictionary and must appear within a tell block targeting the Finder.)

Thus there is a sense in which tell and of are interchangeable. In determining the target, AppleScript actually works its way up the chain of ofs and 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.)

Whether you use of or tell on any particular occasion will depend on various circumstances. Sometimes it's just a matter of style and legibility, but sometimes you'll be constrained by other factors. Suppose you want to open file 1 of folder 1, and then file 1 of folder 2. And suppose your code starts this way:

tell application "Finder"
    tell folder 1

From within this nested tell block, there is absolutely no way to speak of folder 2. You could use the words "folder 2," but you're already inside a tell block targeting folder 1, so this would mean "folder 2 of folder 1," which is not what you want. There isn't any notation that backs you out one level (like .. in a POSIX pathname). You must actually be one level higher. An experienced AppleScript programmer will plan ahead and not nest tell blocks too deeply:

tell application "Finder"
    open file 1 of folder 1
    open file 1 of folder 2
end tell

Another solution is, as you're working your way down the nest of tell blocks, to capture a reference to something you're going to need later at a level too deep to refer to it. For example:

tell application "Microsoft Entourage"
    tell in box folder
        move message 1 to folder "temp"
        -- error: Microsoft Entourage got an error: Can't get message 1 of in box folder
    end tell
end tell

Despite the very misleading error message, the actual problem here is that there is no such thing as folder "temp" of in box folderfolder "temp" is a top-level folder. One way out would of course be not to dive into a tell block:

tell application "Microsoft Entourage"
    move message 1 of in box folder to folder "temp"
end tell

But in a bigger script or with a long chain of ofs, we might not like that solution. So we'll capture a reference to folder "temp" at a point where we can speak of it, and use that reference later:

tell application "Microsoft Entourage"
    set ftemp to folder "temp"
    tell in box folder
        move message 1 to ftemp
    end tell
end tell

11.4.5. Terms in Scope

The rules for targeting do not override the scoping rules described in the previous chapter. A tell block does not cut off access to the surrounding contextand a good thing too, because if it did, you wouldn't be able to use terms that are in scope while explicitly targeting something. AppleScript does not blindly send messages to the target; it looks at the target's terminology, but it also looks to see whether you might be using a term that's in scope from your script. You can therefore quite freely mingle terms defined in the current context of your script with terms defined by the target.

(The mechanism is actually quite subtle, and if you press up against its limits, conflicts can arise. I'll give some examples in this chapter, and there is further detail in the section "Resolution of Terminology" in Chapter 20.)

For example:

set x to "howdy"
tell application "Finder"
    count 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.)

Here's an example with considerable mingling of terms from the two namespaces, yours and the Finder's:

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

Here, oldname and newname are (implicit) globals within the script, and their values are set and retrieved without involving the Finder. To accomplish this, AppleScript must unravel your phrases into separate commands. Consider this line:

    set oldname to name of folder 1

AppleScript actually does two things here. First it sends to the Finder this message (see the later section "Get"):

    get name of folder 1

Then it uses the result to set the value of oldname within your script. There is a clear division of labor: the Finder does not somehow lay hands on any of your script's variables.

But handler calls are different. A handler call will always send a message to the target. This won't work:

on whatNumber( )
    return 1
end whatNumber
tell application "Finder"
    get folder whatNumber( ) -- error: Finder got an error: Can't continue whatNumber
end tell

The Finder is sent the whatNumber message, but it knows of no whatNumber command. (The section "Me," later in this chapter, will provide the solution to this problem.)

11.4.6. Nested Targets

The innermost target of a command is the target. Once AppleScript, working its way outward from a command, has determined a complete target, it stops, ignoring any further ofs or tells that surround it. Consider, for example, the following:

tell application "iTunes"
    tell application "Finder"
        count folders
    end tell
end tell

iTunes 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 "iTunes"

AppleScript literally throws away the mention of iTunes after decompilation:

count folders of application "Finder"

The direct object has primacy in this regard. It always has the potential to constitute a complete target and override all surrounding ofs and tells. For example:

tell application "Finder"
    count "howdy"
end tell

The string "howdy" is a complete target, and no message is sent to the Finder.


Previous Page
Next Page