Using "reference to" on a list in a subroutine produces error

Greetings MacScripters. I have recently encountered a problem that has me scratching my head. The following example from the AppleScript Language Guide (p. 71 of the PDF version) works as advertised so long as it is contained within my script’s run handler (implicit or explicit):

	set bigList to {}
	set bigListRef to a reference to bigList
	set numItems to 10000
	set t to (time of (current date)) --Start timing operations. 
	repeat with n from 1 to numItems
		copy n to the end of bigListRef
	end repeat
	set total to (time of (current date)) - t --End timing. 
	total

However, the exact same statements produce the error “Can’t make last insertion point of bigList into type reference.” when run from within a subroutine as in in the example below. The error occurs on the copy statement.

testThis()

on testThis()
	set bigList to {}
	set bigListRef to a reference to bigList
	set numItems to 10000
	set t to (time of (current date)) --Start timing operations. 
	repeat with n from 1 to numItems
		copy n to the end of bigListRef
	end repeat
	set total to (time of (current date)) - t --End timing. 
	total
end testThis

I really need to employ this technique of accessing a list by reference in a number of subroutines. Any help would be appreciated.

Hi, raneil.

References can only be set up for globals and properties. In the original ASLG script, bigList isn’t in a handler and is therefore a sort of global by default. The value of the bigListRef reference in this case is bigList of «script». It refers to bigList as a something belonging to the script itself.

In a handler, though, variables are local by default and don’t actually “belong” to anything, so it’s not possible to get references to them.

But there’s a fairly well known technique to get round this. It involves using a script object with a property variable that’s set to the list. The property can be referred to as something belonging to the script object. The method doesn’t use ‘a reference to’. Instead, the reference is actually in the text of the script. As such, it produces even faster results than a reference stored in a variable.

testThis()

on testThis()
	script o
		property bigList : {}
	end script
	
	set numItems to 10000
	set t to (time of (current date)) --Start timing operations. 
	repeat with n from 1 to numItems
		set the end of o's bigList to n -- The reference is "o's bigList".
	end repeat
	set total to (time of (current date)) - t --End timing. 
	total
end testThis

If you need to pass a list to the handler:

set myList to {}
testThis(myList)
myList

on testThis(thelist)
	script o
		property bigList : thelist
	end script
	
	set numItems to 10000
	set t to (time of (current date)) --Start timing operations. 
	repeat with n from 1 to numItems
		set the end of o's bigList to n
	end repeat
	set total to (time of (current date)) - t --End timing. 
	total
end testThis

Hope that makes sense. :slight_smile:

Aha! It makes sense NOW! :smiley:

Thanks, Nigel. That’s enormously helpful.