Previous Page
Next Page

11.10. Operations on Multiple References

When an element specifier would return a list of references, it may be possible to ask for an attribute of this list as a shorthand for asking for that attribute of each element of the list in turn; the request to fetch the attribute is applied distributively to each item of the list.

For example, this works, and returns a list of strings, the names of each disk in turn:

tell application "Finder" to get name of every disk

Similarly:

tell application "iTunes"
    tell view of browser window 1
        get name of every track
    end tell
end tell

Possibly you can even apply this construct to the result of a boolean test:

tell application "iTunes"
    tell view of browser window 1
        get database ID of every track whose name contains "Palestrina"
    end tell
end tell

Those examples illustrate a property; the same thing may work for an element:

tell application "Finder"
    get file 1 of every folder
end tell

When you request multiple elements distributed across a list in this way, whether you get back a list of lists or a single flattened list depends upon the individual application. For example:

tell application "Address Book"
    get every email of every person
end tell

The result of that code is a list of liststhe outer list has as many items as there are persons, with each item being a list of every email address of the corresponding person. But when you try something similar in the Finder, the result is a single list of files:

tell application "Finder"
    get every file of every folder
end tell

An application may also be willing to accept a list as the direct object of a command, applying the command distributively to each member of the list. You can't know until you try:

tell application "Microsoft Entourage"
    move (every message of in box folder where address of its sender 
contains "lambert") to folder "temp" end tell

Despite the parentheses inserted by AppleScript's compiler, there's only one Apple event here. You're not getting the list and then sending it back to Entourage for processing: you're describing the list and telling Entourage to construct and process it.

Distribution over a list is a tremendously powerful and efficient construct, where a single Apple event causes the target application to do a lot of work for you. But keep in mind that you can't be certain it will be implemented until you try it. For example, let's say you want to know how long each word of a BBEdit document is. A word has a length property, but you can't fetch this property distributively over the items of a list, possible because length is already a property of a list. So, for example, you can say this:

tell application "BBEdit"
    contents of every word of window 1 -- {"this", "is", "a", "test"}
end tell

But you can't say this:

tell application "BBEdit"
    length of every word of window 1 -- 4
end tell

Well, you can say it, but it doesn't yield the desired answer. Instead of a list of lengths, we were given the length of the list (that is, the number of words in the window). The workaround, when distribution doesn't work, is to loop through the list yourself:

tell application "BBEdit"
    tell document 1
        set L to get contents of every word
        set L2 to {}
        repeat with aWord in L
            set end of L2 to length of aWord
        end repeat
    end tell
end tell

In this case, the workaround was not particularly expensive or unpleasant. But when it involves sending an Apple event every time through the loop, it's a poor substitute.


Previous Page
Next Page