This chapter describes AppleScript control statements. A control statement is a statement that determines when and how other statements are executed or how expressions are evaluated. For example, a control statement may cause AppleScript to skip or repeat certain statements.
Simple statements can be written on one line, while compound statements can contain other statements, including multiple clauses with nested and multi-line statements. A compound statement is known as a statement block.
Compound statements begin with one or more reserved words, such as tell
, that identify the type of control statement. The last line of a compound statement always starts with end
, and can optionally include the word that begins the control statement (such as end tell
).
The considering
and ignoring
statements cause AppleScript to consider or ignore specific characteristics as it executes groups of statements. There are two kinds of considering
and ignoring
statements:
Those that specify attributes to be considered or ignored in performing text comparisons.
Those that specify whether AppleScript should consider or ignore responses from an application.
Specify how AppleScript should treats attributes, such as case, in performing text comparisons.
|
A characteristic of the text:
case
If this attribute is ignored, uppercase letters are not distinguished from lowercase letters. See Special Considerations below for related information. See also greater than, less than
for a description of how AppleScript sorts letters, punctuation, and other symbols.
diacriticals
If this attribute is ignored, text
objects are compared as if no diacritical marks (such as ´, `, ˆ, ¨, and ˜) are present; for example, "résumé"
is equal to "resume"
.
hyphens
If this attribute is ignored, text
objects are compared as if no hyphens are present; for example "anti-war"
is equal to "antiwar"
.
numeric strings
By default, this attribute is ignored, and text strings are compared according to their character values. For example, if this attribute is considered, "1.10.1" > "1.9.4"
evaluates as true
; otherwise it evaluates as false
. This can be useful in comparing version strings.
punctuation
If this attribute is ignored,text
objects are compared as if no punctuation marks (such as . , ? : ; ! ' " `
) are present; for example "What? he inquired."
is equal to "what he inquired"
.
white space
If this attribute is ignored, the text
objects are compared as if spaces, tab characters, and return characters were not present; for example "Brick house"
would be considered equal to "Brickhouse"
.
Any AppleScript statement.
The following examples show how considering
and ignoring
statements for various attributes can change the value of text comparisons.
"Hello Bob" = "HelloBob" --result: false |
ignoring white space |
"Hello Bob" = "HelloBob" --result: true |
end ignoring |
"BOB" = "bob" --result: true |
considering case |
"BOB" = "bob" --result: false |
end considering |
"a" = "√°" --result: false |
ignoring diacriticals |
"a" = "√°" --result: true |
end considering |
"Babs" = "b√°bs" --result: false |
ignoring case |
"Babs" = "b√°bs" --result: false |
end ignoring |
ignoring case and diacriticals |
"Babs" = "b√°bs" --result: true |
end ignoring |
You can nest considering
and ignoring
statements. If the same attribute appears in both an outer and inner statement, the attribute specified in the inner statement takes precedence. When attributes in an inner considering
or ignoring
statement are different from those in outer statements, they are added to the attributes to be considered and ignored.
Because text item delimiters
(described in “version”) respect considering
and ignoring
attributes in AppleScript 2.0, delimiters are case-insensitive by default. Formerly, they were always case-sensitive. To enforce the previous behavior, add an explicit considering case
statement.
Permits a script to continue without waiting for an application to respond to commands that target it.
|
Any AppleScript statement.
The following example shows how to use an ignoring statement so that a script needn’t wait while Finder is performing a potentially lengthy task:
tell application "Finder" |
ignoring application responses |
empty the trash |
end ignoring |
end tell |
Your script may want to ignore most responses from an application, but wait for a response to a particular statement. You can do so by nesting considering
and ignoring
statements:
tell application "Finder" |
ignoring application responses |
empty the trash |
-- other statements that ignore application responses |
considering application responses |
set itemName to name of first item of startup disk |
end considering |
-- other statements that ignore application responses |
end ignoring |
end tell |
A response to an application command indicates whether the command completed successfully, and also returns results and error messages, if there are any. When you use an ignoring application responses
block, you forego this information.
Results and error messages from AppleScript commands, scripting additions, and expressions are not affected by the application responses
attribute.
During script execution, errors can occur in the operating system (for example, when a specified file isn’t found), in an application (for example, when the script specifies an object that doesn’t exist), and in the script itself. An error message is a message that is supplied by an application, AppleScript, or Mac OS X when an error occurs during the handling of a command. An error message can include an error number, which is an integer that identifies the error; an error expression, which is an expression, usually a text
object, that describes the error; and other information.
A script can signal an error—which can then be handled by an error handler—with the error
statement. This allows scripts to supply their own messages for errors that occur within the script. For example, a script can prepare to handle anticipated errors by using a try
statement. In the on error
branch of a try
statement, a script may be able to recover gracefully from the error. If not, it can use an error
statement to resignal the error message it receives, modifying the message as needed to supply information specific to the script.
Signals an error in a script.
|
A text
object describing the error. Although this parameter is optional, you should provide descriptions for errors wherever possible. If you do not include an error description, an empty text
object ("") is passed to the error handler.
The error number for the error. This is an optional parameter. If you do not include a number parameter, the value -2700 (unknown error) is passed to the error handler.
If the error you are signaling is a close match for one that already has an AppleScript error constant, you can use that constant. If you need to create a new number for the error, avoid using one that conflicts with error numbers defined by AppleScript, Mac OS X, and the Apple Event Manager. In general, you should use positive numbers from 500 to 10,000. For more information, see “Error Numbers and Error Messages.”
A list of objects. Applies only to commands that return results for multiple objects. If results for some, but not all, of the objects specified in the command are available, you can include them in the partial result parameter. This is rarely supported by applications.
A reference to the object, if any, that caused the error.
A class. If a parameter specified in the command was not of the expected class, and AppleScript was unable to coerce it to the expected class, then you can include the expected class in the to
parameter.
The following example uses a try
statement to handle a simple error, and demonstrates how you can use an error
statement to catch an error, then resignal the error exactly as it was received, causing AppleScript to display an error dialog (and halt execution):
try |
word 5 of "one two three" |
on error eStr number eNum partial result rList from badObj to expectedType |
-- statements that take action based on the error |
display dialog "Doing some preliminary handling..." |
-- then resignal the error |
error eStr number eNum partial result rList from badObj to expectedType |
end try |
In the next example, an error
statement resignals an error, but omits any original error information and supplies its own message to appear in the error dialog:
try |
word 5 of "one two three" |
on error |
-- statements to execute in case of error |
error "There are not enough words." |
end try |
For more comprehensive examples, see “Working with Errors.”
An if
statement allows you to define statements or groups of statements that are executed only in specific circumstances, based on the evaluation of one or more Boolean expressions.
An if
statement is also called a conditional statement. Boolean expressions in if
statements are also called tests.
Executes a statement if a Boolean expression evaluates to true
.
|
A Boolean expression.
Any AppleScript statement.
This script displays a dialog if the value of the Boolean expression ageOfCat > 1
is true
. (The variable ageOfCat
is set previously.)
if ageOfCat > 1 then display dialog "This is not a kitten." |
Executes a group (or groups) of statements if a Boolean expression (or expressions) evaluates to true
.
|
A Boolean expression.
Any AppleScript statement.
The following example uses a compound if
statement, with a final else
clause, to display a statement based on the current temperature (obtained separately):
if currentTemp < 60 then |
set response to "It's a little chilly today." |
else if currentTemp > 80 then |
set response to "It's getting hotter today." |
else |
set response to "It's a nice day today." |
end if |
display dialog response |
An if
statement can contain any number of else if
clauses; AppleScript looks for the first Boolean expression contained in an if
or else if
clause that is true
, executes the statements contained in its block (the statements between one else if
and the following else if
or else
clause), and then exits the if
statement.
An if
statement can also include a final else
clause. The statements in its block are executed if no other test in the if
statement passes.
You use a repeat
statement to create loops or execute groups of repeated statements in scripts.
There are a number of types of repeat
statement, each differing in the way it terminates the loop. Each of the options, from repeating a loop a specific number of times, to looping over the items in a list, to looping until a condition is met, and so on, lends itself to particular kinds of tasks.
For information on testing and debugging repeat
statements, see “Debugging AppleScript Scripts.”
Terminates a repeat
loop and resumes execution with the statement that follows the repeat
statement.
You can only use an exit
statement inside a repeat
statement. Though most commonly used with the repeat (forever)
form, you can also use an exit
statement with other types of repeat
statement.
|
See the example in repeat (forever)
.
Repeats a statement (or statements) until an exit
statement is encountered.
To terminate a repeat
(forever) statement, you can:
Use an exit
statement and design the logic so that it eventually encounters the exit
statement.
Use a “return”
statement, which exits the handler or script that contains the loop, and therefore the loop as well.
Use a try
statement and rely on an error condition to exit the loop.
|
Any AppleScript statement.
This form of the repeat
statement is similar to the repeat until
form, except that instead of putting a test in the repeat
statement itself, you determine within the loop when it is time to exit. You might use this form, for example, to wait for a lengthy or indeterminate operation to complete:
repeat |
-- perform operations |
if someBooleanTest then |
exit repeat |
end if |
end repeat |
In a script application that stays open, you can use an idle
handler to perform periodic tasks, such as checking for an operation to complete. See “idle Handlers” for more information.
Repeats a statement (or statements) a specified number of times.
|
Specifies the number of times to repeat the statements in the body of the loop.
Instead of an integer, you can specify any value that can be coerced to an integer.
If the value is less than one, the body of the repeat
statement is not executed.
Any AppleScript statement.
The following handler uses the repeat (number) times
form of the repeat
statement to raise a passed number to the passed power:
on raiseToTheNth(x, power) |
set returnVal to x |
repeat power - 1 times |
set returnVal to returnVal * x |
end repeat |
return returnVal |
end raiseToTheNth |
Repeats a statement (or statements) until a condition is met. Tests the condition before executing any statements.
|
A Boolean expression. If it has the value true
when entering the loop, the statements in the loop are not executed.
Any AppleScript statement.
The following example uses the repeat until
form of the repeat
statement to allow a user to enter database records. The handler enterDataRecord()
, which is not shown, returns true
if the user is done entering records:
set userDone to false |
repeat until userDone |
set userDone to enterDataRecord() |
end repeat |
Repeats a statement (or statements) as long as a condition is met. Tests the condition before executing any statements. Similar to the repeat until
form, except that it continues while a condition is true
, instead of until it is true
.
|
A Boolean expression. If it has the value false
when entering the loop, the statements in the loop are not executed.
Any AppleScript statement.
The following example uses the repeat while
form of the repeat
statement to allow a user to enter database records. In this case, we’ve just reversed the logic shown in the repeat until
example. Here, the handler enterDataRecord()
, which is not shown, returns true
if the user is not done entering records:
set userNotDone to true |
repeat while userNotDone |
set userNotDone to enterDataRecord() |
end repeat |
Repeats a statement (or statements) until the value of the controlling loop variable exceeds the value of the predefined stop value.
|
Controls the number of iterations. It can be a previously defined variable or a new variable you define in the repeat
statement.
Specifies a value that is assigned to loopVariable when the loop is entered.
You can specify an integer or any value that can be coerced to an integer.
Specifies an value. When that value is exceeded by the value of loopVariable, iteration ends. If stopValue is less than startValue, the body is not executed.
You can specify an integer or any value that can be coerced to an integer.
Specifies a value that is added to loopVariable after each iteration of the loop. You can assign an integer
or a real
value; a real
value is rounded to an integer
.
Any AppleScript statement.
The following handler uses the repeat with loopVariable (from startValue to stopValue)
form of the repeat
statement to compute a factorial value (the factorial of a number is the product of all the positive integers from 1 to that number):
on factorial(x) |
set returnVal to 1 |
repeat with n from 2 to x |
set returnVal to returnVal * n |
end repeat |
return returnVal |
end factorial |
You can use an existing variable as the loop variable in a repeat with loopVariable (from startValue to stopValue)
statement or define a new one in the statement. In either case, the loop variable is defined outside the loop. You can change the value of the loop variable inside the loop body but it will get reset to the next loop value the next time through the loop. After the loop completes, the loop variable retains its last value.
AppleScript evaluates startValue, stopValue, and stepValue when it begins executing the loop and stores the values internally. As a result, if you change the values in the body of the loop, it doesn’t change the execution of the loop.
Loops through the items in a specified list.
The number of iterations is equal to the number of items in the list. In the first iteration, the value of the variable is a reference to the first item in list, in the second iteration, it is a reference to the second item in list, and so on.
|
Any previously defined variable or a new variable you define in the repeat
statement (see Discussion).
A list or a object specifier (such as words 1 thru 5
) whose value is a list.
list can also be a record; AppleScript coerces the record to a list (see Discussion).
Any AppleScript statement.
The following script examines a list of words with the repeat with loopVariable (in list)
form of the repeat
statement, displaying a dialog if it finds the word “hammer” in the list. Note that within the loop, the loop variable (currentWord
) is a reference to an item in a list, so in the test statement (if contents of currentWord is equal to "hammer" then
) it must be cast to text (as text
).
set wordList to words in "Where is the hammer?" |
repeat with currentWord in wordList |
log currentWord |
if contents of currentWord is equal to "hammer" then |
display dialog "I found the hammer!" |
end if |
end repeat |
The statement log currentWord
logs the current list item to Script Editor’s log window. For more information, see “Debugging AppleScript Scripts.”
You can use an existing variable as the loop variable in a repeat with loopVariable (in list)
statement or define a new one in the repeat with…
statement. In either case, the loop variable is defined outside the loop. You can change the value of the loop variable inside the loop body but it will get reset to the next loop value the next time through the loop. After the loop completes, the loop variable retains its last value.
AppleScript evaluates loopVariable in
list as an object specifier that takes on the value of item 1 of list
, item 2 of list
, item 3 of list
, and so on until it reaches the last item in the list, as shown in the following example:
repeat with i in {1, 2, 3, 4} |
set listItem to i |
end repeat |
--result: item 4 of {1, 2, 3, 4} --result: an object specifier |
To set a variable to the value of an item in the list, rather than a reference to the item, use the contents of
property:
repeat with i in {1, 2, 3, 4} |
set listItem to contents of i |
end repeat |
--result: 4 |
You can also use the list items directly in expressions:
set total to 0 |
repeat with i in {1, 2, 3, 4} |
set total to total + i |
end repeat |
--result: 10 |
If the value of list is a record, AppleScript coerces the record to a list by stripping the property labels. For example, {a:1, b:2, c:3}
becomes {1, 2, 3}
.
A tell
statement specifies the default target—that is, the object to which commands are sent if they do not include a direct parameter. Statements within a tell
statement that use terminology from the targeted object are compiled against that object’s dictionary.
The object of a tell
statement is typically a reference to an application object or a script
object. For example, the following tell
statement targets the Finder application:
tell application "Finder" |
set frontWindowName to name of front window |
-- any number of additional statements can appear here |
end tell |
You can nest tell
statements inside other tell
statements, as long as you follow the syntax and rules described in tell (compound)
.
When you need to call a handler from within a tell
statement, there are special terms you use to indicate that the handler is part of the script and not a command that should be sent to the object of the tell
statement. These terms are described in “The it and me Keywords” and in “Calling Handlers in a tell Statement.”
A tell
statement that targets a local application doesn’t cause it to launch, if it is not already running. For example, a script can examine the is running
property of the targeted application
object to determine if the application is running before attempting to send it any commands. If it is not running it won’t be launched.
If a tell
statement targets a local application and executes any statements that require a response from the application, then AppleScript will launch the application if it is not already running. The application is launched as hidden, but the script can send it an activate
command to bring it to the front, if needed.
A tell
statement that targets a remote application will not cause it to launch—in fact, it will not compile or run unless the application is already running. Nor is it possible to access the is running
property of an application on a remote computer.
Specifies a target object and a command to send to it.
|
Any object. Typically an object specifier or a reference
object (which contains an object specifier).
Any AppleScript statement.
This simple tell
statement closes the front Finder window:
tell front window of application "Finder" to close |
For more information on how to specify an application object, see the application
class.
Specifies a target object and one or more commands to send to it. A compound tell
statement is different from a simple tell
statement in that it always includes an end
statement.
|
Any object. Typically an object specifier or a reference
object (which contains an object specifier).
Any AppleScript statement, including another tell
statement.
The following statements show how to close a window using first a compound tell
statement, then with two variations of a simple tell
statement:
tell application "Finder" |
close front window |
end tell |
tell front window of application "Finder" to close |
tell application "Finder" to close front window |
The following example shows a nested tell
statement:
tell application "Finder" |
tell document 1 of application "TextEdit" |
set newName to word 1 -- handled by TextEdit |
end tell |
set len to count characters in newName -- handled by AppleScript |
if (len > 2) and (len < 15) then -- comparisons handled by AppleScript |
set name of first item of disk "HD" to newName -- handled by Finder |
end if |
end tell |
This example works because in each case the terminology understood by a particular application is used within a tell
block targeting that application. However, it would not compile if you asked the Finder for word 1
of a document, or told TextEdit to set name
of the first item on a disk, because those applications do not support those terms.
A try
statement provides the means for scripts to handle potential errors. It attempts to execute one or more statements and, if an error occurs, executes a separate set of statements to deal with the error condition. If an error occurs and there is no try
statement in the calling chain to handle it, AppleScript displays an error and script execution stops.
For related information, see “error Statements” and “AppleScript Error Handling.”
Attempts to execute a list of AppleScript statements, calling an error handler if any of the statements results in an error.
A try
statement is a two-part compound statement that contains a series of AppleScript statements, followed by an error handler to be invoked if any of those statements causes an error. If the statement that caused the error is included in a try
statement, then AppleScript passes control to the error handler. After the error handler completes, control passes to the statement immediately following the end of the try
statement.
|
Any AppleScript statement.
A text
object, that describes the error.
The error number, an integer. For possible values, see “Error Numbers and Error Messages.”
A reference to the object, if any, that caused the error.
A list that provides partial results for objects that were handled before the error occurred. The list can contain values of any class. This parameter applies only to commands that return results for multiple objects. This is rarely supported by applications.
The expected class. If the error was caused by a coercion failure, the value of this variable is the class of the coercion that failed. (The second example below shows how this works in a case where AppleScript is unable to coerce a text
object into an integer
.)
Either a global variable or a local variable that can be used in the handler. A variable can contain any class of value. The scope of a local variable is the handler. The scope of a global variable extends to any other part of the script, including other handlers and script
objects. For related information about local and global variables, see “version.”
The following example shows how you can use a try
statement to handle the “Cancel” button for a display alert
command. Canceling returns an error number of -128, but is not really an error. This test handler just displays a dialog to indicate when the user cancels or when some other error occurs.
try |
display alert "Hello" buttons {"Cancel", "Yes", "No"} cancel button 1 |
on error errText number errNum |
if (errNum is equal to -128) then |
-- User cancelled. |
display dialog "User cancelled." |
else |
display dialog "Some other error: " & errNum & return & errText |
end if |
end try |
You can also use a simplified version of the try
statement that checks for just a single error number. In the following example, only error -128 is handled. Any other error number is ignored by this try
statement, but is automatically passed up the calling chain, where it may be handled by other try
statements.
try |
display alert "Hello" buttons {"Cancel", "Yes", "No"} cancel button 1 |
on error number -128 |
-- Either do something special to handle Cancel, or just ignore it. |
end try |
The following example demonstrates the use of the to
keyword to capture additional information about an error that occurs during a coercion failure:
try |
repeat with i from 1 to "Toronto" |
-- do something that depends on variable "i" |
end repeat |
on error from obj to newClass |
log {obj, newClass} -- Display from and to info in log window. |
end try |
This repeat
statement fails because the text
object "Toronto"
cannot be coerced to an integer
. The error handler simply writes the values of obj
(the offending value, "Toronto"
) and newClass
(the class of the coercion that failed, integer
) to Script Editor’s Event Log History window (and to the script window’s Event Log pane). The result is “(*Toronto, integer*)”, indicating the error occurred while trying to coerce “Toronto” to an integer.
For additional examples, see “Working with Errors.”
A using terms from
statement lets you specify which terminology AppleScript should use in compiling the statements in a script. Whereas a tell
statement specifies the default target (often an application) to which commands are sent and the terminology to use, a using terms from
statement specifies only the terminology.
A using terms from
statement can be useful in writing application event handler scripts, such as Mail rules.
Another use for this type of statement is with a script that targets an application on a remote computer that may not be available when you compile the script (or the application may not be running). Or, you might be developing locally and only want to test with the remote application at a later time. In either case, you can use a using terms from
statement to specify a local application (presumably with a terminology that matches the one on the remote computer) to compile against.
Even if a statement contained within a using terms from
statement compiles, the script may fail when run because the target application’s terminology may differ from that used in compiling.
You can nest using terms from
statements. When you do so, each script statement is compiled against the terminology of the application named in the innermost enclosing using terms from
statement.
Instructs AppleScript to use the terminology from the specified application in compiling the enclosed statements.
|
A specifier for an application object.
Any AppleScript statement.
The following example shows how to use a using terms from
statement in writing a Mail rule action script. These scripts take the following form:
using terms from application "Mail" |
on perform mail action with messages theMessages for rule theRule |
tell application "Mail" |
-- statements to process each message in theMessages |
end tell |
end perform mail action with messages |
end using terms from |
To use the script, you open Preferences for the Mail application, create or edit a rule, and assign the script as the action for the rule.
For an example that works with an application on a remote machine, see “Targeting Remote Applications.”
You can use a with timeout
statement to control how long AppleScript waits for a command to execute before timing out. By default, when an application fails to respond to a command, AppleScript waits for two minutes before reporting an error and halting execution.
Specifies how long AppleScript waits for a response to a command that is sent to another application.
|
The amount of time, in seconds, AppleScript should wait before timing out (and interrupting the command).
Any AppleScript statement.
The following script tells TextEdit to close its first document; if the document has been modified, it asks the user if the document should be saved. It includes the statement with timeout of 20 seconds
, so that if the user doesn’t complete the close
operation within 20 seconds, the operation times out.
tell application "TextEdit" |
with timeout of 20 seconds |
close document 1 saving ask |
end timeout |
end tell |
When a command fails to complete in the allotted time (whether the default of two minutes, or a time set by a with timeout
statement), AppleScript stops running the script and returns the error "event timed out"
. AppleScript does not cancel the operation—it merely stops execution of the script. If you want the script to continue, you can wrap the statements in a try
statement. However, whether your script can send a command to cancel an offending lengthy operation after a timeout is dependent on the application that is performing the command.
A with timeout
statement applies only to commands sent to application objects, not to commands sent to the application that is running the script.
In some situations, you may want to use an ignoring application responses
statement (instead of a with timeout
statement) so that your script needn’t wait for application commands to complete. For more information, see “considering and ignoring Statements.”
When you execute a script, AppleScript may send one or more Apple events to targeted applications. A transaction is a set of operations that are applied as a single unit—either all of the changes are applied or none are. This mechanism works only with applications that support it.
Associates a single transaction ID with any events sent to a target application as a result of executing commands in the body of the statement.
|
An object that identifies a specific session.
Any AppleScript statement.
This example uses a with transaction
statement to ensure that a record can be modified by one user without being modified by another user at the same time. (In the following examples, “Small DB” and “Super DB” are representative database applications.)
tell application "Small DB" |
with transaction |
set oldName to Field "Name" |
set oldAddress to Field "Address" |
set newName to display dialog ¬ |
"Please type a new name" ¬ |
default answer oldName |
set newAddress to display dialog ¬ |
"Please type the new address" ¬ |
default answer oldAddress |
set Field "Name" to newName |
set Field "Address" to newAddress |
end transaction |
end tell |
The set
statements obtain the current values of the Name and Address fields and invite the user to change them. Enclosing these set
statements in a single with transaction
statement informs the application that other users should not be allowed to access the same record at the same time.
A with transaction
statement works only with applications that explicitly support it. Some applications only support with transaction
statements (like the one in the previous example) that do not take a session object as a parameter. Other applications support both with transaction
statements that have no parameter and with transaction
statements that take a session parameter.
The following example demonstrates how to specify a session for a with transaction
statement:
tell application "Super DB" |
set mySession to make session with data {user: "Bob", password: "Secret"} |
with transaction mySession |
... |
end transaction |
end tell |
Last updated: 2008-03-11