Very strange modifying of property

Hi everyone,

I have a very long AS Studio app. I found that the source of a bug was that a property, which is a list, was getting changed even though it was never set to anything!

I have a variable that I set TO the list, and then modify the variable, but never modify the actual property. Yet it changes with each modification of the variable.

I extracted the relevant code that reproduces the problem.


property C9FlavorTemplate : {"Townie", "Townie", "Townie", "Townie", "Townie", "Mafia Goon", "Mafia Goon"}
property C9Flavors : {"00 (No Cop, No Doc)", "01 (Doc, no Cop)", "10 (Cop, no Doc)", "11 (Cop and Doc)"}

tell me to generateRoles()

to generateRoles()
	set randomList to my getRandomList()
	set C9FlavorRoleList to my getC9FlavorList()
end generateRoles

to getRandomList()
	set randomDotOrgURL to "http://random.org/sequences/?min=1&max=7&format=plain&rnd=new"
	set AppleScript's text item delimiters to return
	set roleResult to text items 1 thru 7 of (do shell script "curl -k -w 10 " & quoted form of randomDotOrgURL)
	set AppleScript's text item delimiters to ""
	return roleResult
end getRandomList

to getC9FlavorList()
	set randomDotOrgURL to "http://random.org/integers/?num=1&min=1&max=4&col=1&base=10&format=plain&rnd=new"
	set flavor to text item 1 of (do shell script "curl -k -w 10 " & quoted form of randomDotOrgURL) as integer
	set thisFlavorList to C9FlavorTemplate
	if flavor = 1 then return thisFlavorList
	if flavor = 2 then set item 2 of thisFlavorList to "Doctor"
	if flavor = 3 then set item 1 of thisFlavorList to "Cop"
	if flavor = 4 then
		set item 1 of thisFlavorList to "Cop"
		set item 2 of thisFlavorList to "Doctor"
	end if
	return thisFlavorList
end getC9FlavorList

What happens is that making changes to the variable “thisFlavorList” changes the items in the property “C9FlavorTemplate.”

Thus the “C9FlavorTemplate” doesn’t stay as a template and screws up the second run of the script.

Is this normal behavior?

To see the bug, run the script in the debugger and see the values in the property “C9FlavorTemplate” change as changes are made to the variable thisFlavorList.

Yes.

It’s not a bug. In your example, when you set the ‘thisFlavorList’ variable to ‘C9FlavorTemplate’, you’re not setting it to what the template variable contains, you’re setting it as a reference to the variable itself. Thus, if you change thisFlavorList, you’re implying (albeit, unknowingly) that you want change the variable it references, not the copy that you’d like to be working with. What you need to do when creating your temporary variable is to explicitly copy the template variable using the copy command…

--> This line...
set thisFlavorList to C9FlavorTemplate

--> Should be...
copy C9FlavorTemplate to thisFlavorList

Thanks for the prompt reply. I thought it might be something like that.

So the rule is, when you use the “set” command from a property, it sets a reference, whereas the “set” command on another variable sets the contents (i.e. is the same as doing a “copy”)?

Interesting. I thought that I would have to do an explicit “a reference to” to get that behavior.

I suppose it is similar to setting one object equal to another in other OOP languages - all it does it point the two items to the same object in memory.

And now I know the answer to why there even IS a “copy” command. I have never used it in many years of writing AppleScripts.

Are there any other situations besides properties that make a reference instead of a copy when the “set” command is used?