AppleScript_ The Definitive Guide - Matt Neuburg [113]
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.
Assignment of Multiple Attributes
Recall 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 attributes , 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 code sets the name first, and afterwards there is no longer a folder "Mannie" to set the comment of, so the attempt to set the comment of folder "Mannie" causes a runtime error.
Object String Specifier
For certain objects in the "real world" (that is, the real world inside the computer), AppleScript has a bootstrap problem. It needs a way to refer to these objects, yet they are not attributes of anything. In fact, they are the things that have attributes. So in order to talk about anything at all outside of the script, AppleScript must pull itself up by its bootstraps.
The solution is an object described using the name of the class followed by a string. It looks rather like an element specifier by name; but the object isn't an element of anything, and the string isn't exactly a name. There is no official term for this construct in Apple's documentation, so I call it an object string specifier . The main real-world objects for which object string specifiers are used are applications,