Online Book Reader

Home Category

AppleScript_ The Definitive Guide - Matt Neuburg [154]

By Root 1443 0
+ 1

end repeat

end tell

total --50

I've got only six folders on my desktop, so where did the number 50 come from? To put it another way, what did we just cycle through? The answer is that we didn't cycle through each folder; we cycled through each item inside each folder. (So 50 is the total number of files and folders inside the six folders on my desktop.) Here's why. When you talk like this, AppleScript does not ask the target application for a list of all the things you specify. Instead, it merely asks the target application for a count of those things. And it asks for this count in a very strange form:

count every class each item

Most applications simply shrug off this extra "each item"; most of their classes don't have an element called item, so they ignore this part of the command. For example, when you say this:

tell application "Microsoft Entourage"

repeat with x in every contact

AppleScript asks Entourage to "count every contact each item." Entourage contacts don't have an item element, so Entourage treats this as if it were "count every contact" and simply reports the number of contacts. But in the Finder, a folder does have items, so the Finder obligingly totals up the number of items within each folder and reports that total.

This is not, however, simply an odd behavior on the part of the Finder; my point is what AppleScript does. We've just seen that when you say this:

repeat with x in every class

AppleScript does not gather a list. It merely obtains a number. So how on earth does it perform the loop? In other words, what is x every time through the loop? When you say this:

tell application "Microsoft Entourage"

repeat with x in every contact

then on successive passes through the loop the value of x is this:

a reference to item 1 of every contact

a reference to item 2 of every contact

a reference to item 3 of every contact

And so on. AppleScript uses the class you asked for to form a reference to a particular item of the list that would be generated if we actually asked for it. But it doesn't ask for that list unless you try to fetch that item. This looks at first blush like an optimization, but if you think about, it's really quite the opposite. Consider what happens when you run this script:

tell application "Microsoft Entourage"

repeat with x in every contact

get name of x

end repeat

end tell

That is already a wasteful script, as you could have obtained the names of all contacts with a single Apple event by asking for "name of every contact." But it's even more wasteful than you might suppose. Each time through the loop, you are not asking for "name of contact 1," "name of contact 2," and so forth. You are asking for "name of item 1 of every contact," "name of item 2 of every contact," and so forth. In other words, you are asking Entourage to form a list of all contacts, every time through the loop! That's unnecessary, because the list doesn't change.

This situation gets even worse if the list you're asking for is to be generated in a more complicated way. Here is some code where we try to get BBEdit to change all words that start with "t" to the word "howdy":

tell application "BBEdit"

repeat with w in (every word of document 1 where its text begins with "t")

set text of w to "howdy"

end repeat

end tell

There are two problems with this code. First, it's incredibly wasteful, because every time through the loop, w is something like this:

a reference to item x of every word of window 1 of application "BBEdit" ¬

where its text begins with "t"

Thus, if we do anything with w, we are asking BBEdit to perform this complicated boolean test (every word of window 1 where its text begins with "t") every time through the loop!

The second problem is that the code doesn't work. If there are two words starting with "t" in the document, it fails with a runtime error. The reason is that the second time through the loop, we are asking for this:

a reference to item 2 of every word of window 1 of application "BBEdit" ¬

where its text begins with "t"

But there is no such

Return Main Page Previous Page Next Page

®Online Book Reader