How to avoid errors when using a loop variable
When looping through a list in a repeat with block using the with form, be careful how you test the loop variable. The following code snippet looks like it should return the value 2, but it doesn’t because the test for equality with 2 is never satisfied:
repeat with i in {1, 2, 3}
if i is 2 then
exit repeat
end if
end repeat
i --> item 3 of {1, 2, 3}
As you see from the final value of i, the snippet looped all the way through the list and exited only when the list was exhausted. To get to the bottom of the problem, try this:
repeat with i in {1, 2, 3}
class of i --> integer
i --> item 1 of {1, 2, 3}, item 2 of {1, 2, 3}, etc.
if i is 2 then --it never is 2!
exit repeat
end if
end repeat
i --> item 3 of {1, 2, 3}
Single-stepping through this snippet using an advance script editor, we see that the class property of each list element is reported as integer, which demonstrates that the loop variable is evaluated to its contents when determining its class. However, the loop variable is not evaluated to its contents when performing the equality test. So, to be safe, you should always test the contents of a loop variable, not the loop variable itself, like so:
repeat with i in {1, 2, 3}
class of (contents of i) -->integer
contents of i -->1, 2, etc.
if contents of i is 2 then
exit repeat
end if
end repeat
contents of i -->2
Or, in simpler form:
repeat with i in {1, 2, 3}
if contents of i is 2 then
exit repeat
end if
end repeat
contents of i --2
Or, in the safest form (from the viewpoint of a forgetful scripter), always reset the loop variable to its contents before attempting to use its value for any purpose:
repeat with i in {1, 2, 3}
set i to contents of i
if i is 2 then
exit repeat
end if
end repeat
i -->2
You might think this is a bug in AppleScript, but it isn’t. A loop variable in the with form of the repeat loop is a reference to an object, not the value of the object. Like many AppleScript gotchas, this one is actually explained in the AppleScript Language Guide: “To get the value of an item in the list, you must use the contents of operator” (emphasis added). Moral: read the manual!”not once, but twice, thrice, or whatever it takes.