I was bit by a scope/reference issue in a subroutine. I had assumed that using a subroutine, even with different variable names, would not modify the input value because the local scope of the variables inside and outside of the subroutine would not effect each other but I was wrong. Consider the following example:
In the first part of the script, using the “modify_the_list_contents” I get the desired results, a new modified list leaving the input list untouched. This is because I had to change the input value from a reference to the object’s contents to the actual contents. In the second value I don’t make this distinction and running the subroutine actually modifies the external value because it is using the reference. This is probably covered in depth somewhere but I just spent hours trying to solve a bug where my initial value was changing because of a subroutine that modified the reference instead of the contents (not what I wanted).
That’s right. It’s only the variables that are either local or global. The data to which they point are the same.
In your modify_the_list_contents() handler, you’ve got round this by setting my_list to ‘my_list’s contents’. This is the same as setting it to ‘my_list’s items’. It sets my_list to another list containing exactly the same items. You can change the new list without changing the original. But if one of the items is itself a list, changing its contents will change the contents of that sublist in the original:
set my_list to {{1, 2, 3}, 2, 3}
set c_list to my_list's contents
set item 2 of c_list to "Hello"
my_list
--> {{1, 2, 3}, 2, 3}
-- But:
set item 2 of item 1 of c_list to "Hello"
my_list
--> {{1, "Hello", 3}, 2, 3}
For a completely new list with no shared data, there’s the ‘copy’ command:
set my_list to {{1, 2, 3}, 2, 3}
copy my_list to c_list
set item 2 of item 1 of c_list to "Hello"
my_list
--> {{1, 2, 3}, 2, 3}
In a handler, that could of course be:
on modify_the_list_contents(my_list)
set copy my_list to my_list
-- etc.
Hi, Jon. Sorry, I didn’t notice your explanation of the behaviour before replying above.
Going into Precise Language Mode, I differentiate between a “reference” (an AppleScript construct that describes how one item relates to another) and a “pointer” (which is how the value of a variable, or of a list item, is located in memory). What’s passed to a handler as a parameter is a copy of the pointer that points the way to the physical location of the data in memory. If it were a reference, dereferencing it with the ‘contents of’ operator would simply return the original item, and you’d still be having problems with shared data.