[ Team LiB ] |
15.7 Who Performs an OperationSome operations within an interapplication communications context can be performed by the target application rather than AppleScript. There are two cases to consider. The operation may appear as a bare expression (for example, the condition in an if clause); I will call this a direct operation. Or, the operation may be part of a boolean test element specifier. 15.7.1 Direct OperationsAccording to Apple's documentation, if the first operand of a direct operation is a reference to an object of the target application, the target application performs the operation. So, for example: tell application "Finder" if the name of folder 1 contains "e" then The comparison performed by the keyword contains is one of the operations that can be performed by the target application. The object the name of folder 1 is a Finder object, so in this case the Finder should perform the operation. In fact, though, experimentation shows that the Finder does not perform the operation; AppleScript does try to get it to do so, but the target application replies with an error indicating that it doesn't wish to perform that sort of operation. AppleScript thereupon adopts a new strategy: it asks the target application for the values in question, and performs the operation itself. So, the way AppleScript first tries to deal with the operation in the previous example is by sending the Finder a single Apple event that means: "Please tell me whether the name of your folder 1 contains "e"." The Finder replies with an error message, so then AppleScript goes back to the Finder and sends it another Apple event that means: "Okay, never mind that, just tell me the name of your folder 1." The Finder complies, and now AppleScript looks, itself, to see whether the result contains "e". This approach seems wasteful, but it is only wasteful the first time. The second time the same sort of code is encountered, the AppleScript scripting component remembers that the Finder doesn't do this sort of operation, and skips the first step; it just asks the Finder for the value of the operand and does the operation itself. In fact, I have not found any application that appears willing to perform direct operations when AppleScript asks it to! The entire matter is therefore moot. One can see, all the same, that the mechanism is a good idea. Suppose both operands are objects belonging to the target application; for example, we might want the Finder to perform this comparison: tell application "Finder" if the name of folder 1 is the name of folder 2 then It would be efficient to be able to send the Finder a single Apple event saying: "Please tell me whether the name of folder 1 and the name of folder 2 are the same." As it is, AppleScript ends up sending the Finder two Apple events: one asking for the name of folder 1, the second asking for the name of folder 2. It then performs the comparison itself. 15.7.2 Boolean Test Element SpecifiersIn a boolean test element specifier (see Chapter 10), the target application always performs the comparison itself. For example: tell application "Finder" name of every folder whose name contains "E" end tell That is a single Apple event; the Apple event includes instructions to use contains "E" as the criterion for returning folder names, so the Finder must implement contains in order to obey. Differences between an application's implementation of an operator and AppleScript's implementation can arise under these circumstances. This seems rather scary, but if the application is well-behaved, these differences should be minor. The primary case in point is the use of considering clauses. For example: tell application "Finder"
considering case
name of every folder whose name contains "E"
end considering
end tell
-- {"emptyFolder", "Test Me"}
The Finder gives the wrong answer; if you consider case, neither of these folder names contains "E". The Finder is simply ignoring the considering clause. In fact, I don't know of any application that considers considering clauses in a string comparison. See Section 12.6.2. The workaround in a situation like this is to take a two-step approach: fetch all the values and then have AppleScript perform the test itself. AppleScript does not implement boolean test element specifiers for lists, so the test must be performed as a loop. So: tell application "Finder" set L to name of every folder end tell set L2 to {} considering case repeat with aName in L if aName contains "E" then set end of L2 to contents of aName end if end repeat end considering After that, L2 contains the right answer. |
[ Team LiB ] |