AppleScript_ The Definitive Guide - Matt Neuburg [151]
There are also some special commands for hustling things along by leaping completely out of the repeat block from inside it. These are the premature terminations of a repeat block. They can be used with any form of repeat block. Here they are:
exit repeat
This statement exits the innermost repeat block in which it occurs. Execution resumes after the end repeat line.
try block
If the repeat block is inside a try block, throwing an error exits the repeat block by virtue of the fact that it exits the try block. See "Errors," later in this chapter.
return
A return statement exits the repeat block by virtue of the fact that it terminates execution of the handler or script.
Repeat Forever
A repeat block with no whatKindOfRepeat condition repeats forever. Obviously you don't really want it to repeat forever, so it's up to you to supply a way out by using one of the three premature terminations.
repeat
display dialog "Prepare to loop forever."
exit repeat
end repeat
display dialog "Just kidding."
Repeat N Times
A repeat block where whatKindOfRepeat is an integer followed by the keyword times repeats that number of times (unless the block terminates prematurely). The integer can be a variable.
repeat 3 times
display dialog "This is really boring."
end repeat
display dialog "ZZzzzz...."
An interesting misuse of this construct is as a workaround for AppleScript's lack of a next repeat or continue keyword. (This idea was suggested to me by Paul Berkowitz, who attributes it to Ray Robertson.) The problem is that you can short-circuit a repeat block by exiting it completely, but you cannot, as you can in many languages, short-circuit it by proceeding immediately to the next iteration of the loop. The workaround is to embed a one-time repeat block within your repeat block; an exit repeat within this one-time repeat block works as a next repeat with respect to the outer repeat block. This device has some shortcomings (it prevents exit repeat from doing its proper job), and it doesn't accomplish anything you couldn't manage with an if block, but in a large script it can make your code easier to read and maintain.
In this (silly) example, we add only the positive items of a list:
set L to {2, -5, 33, 4, -7, 8}
set total to 0
repeat (count L) times
repeat 1 times
set x to item 1 of L
set L to rest of L
if x < 0 then exit repeat
set total to total + x
end repeat
end repeat
total -- 47
For another useful misuse of this construct, see "Blocks" in Chapter 5.
Repeat While
A repeat block where whatKindOfRepeat is the keyword while followed by a boolean condition tests the condition before each repetition. If the condition is true, the block is executed. If the condition is false, the block is not executed and that's the end of the loop; execution resumes after the end repeat line. The idea is that in the course of looping something will eventually happen that will make the condition false.
set response to "Who's there?"
repeat while
response = "Who's there?"
set response to button returned of ¬
(display dialog "Knock knock!" buttons {"Enough!", "Who's there?"})
end repeat
Repeat Until
A repeat block where whatKindOfRepeat is the keyword until followed by a boolean condition tests the condition before each repetition. If the condition is false, the block is executed. If the condition is true, the block is not executed and that's the end of the loop; execution resumes after the end repeat line. This construct is technically unnecessary, as the very same thing could have been achieved by reversing the truth value of the condition of a repeat while block—that is to say, repeat until is exactly the same as repeat while not.
set response to ""
repeat until response