Hi. I finally got down to writing my Christmas cards this evening, so this reply is to the state of this thread when I downloaded it several hours ago.
I hope you’ll excuse a couple of nitpickings about the opening encryption and decryption scripts. Both points concern the first and last lines inside the ‘considering case’ blocks.
set p_letter_list to text items of words_to_encrypt
That should be ‘characters of words_to_encrypt’. A string’s ‘text items’ depend on the current value of AppleScript’s text item delimiters. The default value of these delimiters is {“”} and, when they’re set to this, the string’s ‘text items’ are the same as its ‘characters’. But if, for some reason, the delimiters had been set to some other value elsewhere in the script “ say, for argument, to “encrypt” “ the text items of words_to_encrypt would be {"I want to “, " sentences. Not just words!”}. If you’re going to use ‘text items’, it’s good practise to set the text item delimiters explicitly beforehand “ though in this case it’s better to use the term ‘characters’.
set c_string to c_letter_list as string
Similarly, when a list is coerced to string, the result is affected by current setting of the text item delimiters, which are inserted between each item in the list. So it’s a good idea to be explicit about the delimiter setting here too:
set astid to AppleScript's text item delimiters -- Note the current delimiter setting.
set AppleScript's text item delimiters to {""} -- or "" -- Set the delimiters to an empty string.
set c_string to c_letter_list as string -- Do the list coercion in that state.
set AppleScript's text item delimiters to astid -- Restore the previous delimiter setting.
c_string
More accurately, it’s to do with differences in the way AppleScript handles lists when they’re referred to by variables and when they’re referred to by references to variables. In the encryption script above, there’s this line:
set this_char to item j of charList
Here, the list is referred to by the variable charList. When handling the expression ‘item j of charList’, AppleScript carries out certain safety checks which include, I believe, a check to make sure that the list doesn’t contain itself.
Since charList is a top-level variable (ie. not in a handler) it’s technically a global “ though it may need to be explicitly declared as such to be accessed from inside a handler. Globals and top-level properties “belong” to the script in which they occur, so it’s possible to refer to them in relation to the script itself, which is called ‘me’ in AppleScript.
set this_char to item j of my charList -- NB. 'my'.
A possessive expression like ‘my charList’ or ‘item j of charList’ is called a “reference”. ‘item j of charList’ is a reference to an item in the list held by charList; ‘my charList’ is a reference to the variable charList itself. It’s when we combine these “ including a reference to the list variable in the reference to the list item, as in the example immediately above “ that we see the increase in speed. For some reason, AppleScript doesn’t carry out the safety checks in this case, and the time saved by not doing them makes an enormous difference to overall time.
Inside a handler, variables are, by default, local. Locals are just temporary and don’t “belong” to anything, so it’s not possible to set up references to them. However, it’s possible, while they exist, to give them custody of some data called a “script object”, which is a sort of script-within-a-script. A script object can have its own properties and it’s possible to have references to these. So by assigning a list to a property of a script object, we’re able to use the list-variable reference syntax locally within a handler. The script object doesn’t physically contain the list or affect it in any way. It merely provides a referenceable variable whereby we can refer to it.
The speed gain, by the way, only occurs when the reference to the list variable is included in a reference to one or more of the list’s elements or properties. There’s no gain with processes that act on the list itself, such as ‘count’, ‘contains’, ‘is in’. In fact, referencing the list variable may even slow them down v-e-r-y slightly.
-- In this illustration:
-- 'myList' is a top-level variable;
-- 'theList' is a local variable within the handler;
-- 'l' is a property of the script object held in the handler's local variable 'o'.
-- The list is the same physical entity in each case, only the variables are local or global.
set myList to {1, 2, 3, 4, 5} -- Imagine this list as being much longer.
myHandler(myList)
on myHandler(theList)
script o
property l : theList
end script
set c to (count theList) -- marginally faster than '(count o's l)'.
repeat with i from 1 to c
get item i of o's l -- very much faster than 'item i of theList'.
end repeat
end myHandler