"a reference to" trick no longer applies for leopard?

This trick is supposed to enable faster interation of large lists, however if you compare the first script with the second script, the first script runs faster.

Or perhaps I am not applying the trick correctly.


tell application "iTunes"
	--construct a list of tracks to be transcoded
	set tracklist to {}
	set alactrack to tracks of playlist "Library" whose kind is "Apple Lossless audio file" and enabled is true
	repeat with trackn in alactrack
		if ((count of (tracks of playlist "Library" whose (name is (get name of trackn)) and (time is (get time of trackn)) and kind is "AAC audio file")) = 0) then set end of tracklist to trackn
	end repeat
	
	if length of tracklist > 0 then
		set currentencoder to current encoder
		set current encoder to encoder "AAC Encoder"
		with timeout of 24 * 60 * 60 seconds
			set convertedtracks to convert tracklist
		end timeout
		repeat with trackn in tracklist
			set enabled of trackn to false
		end repeat
	end if
end tell

tell application "iTunes"
	--construct a list of tracks to be transcoded
	set tracklist to {}
	set alactrack to a reference to tracks of playlist "Library" whose kind is "Apple Lossless audio file" and enabled is true
	repeat with trackn in alactrack
		if ((count of (tracks of playlist "Library" whose (name is (get name of trackn)) and (time is (get time of trackn)) and kind is "AAC audio file")) = 0) then set end of tracklist to trackn
	end repeat
	
	if length of tracklist > 0 then
		set currentencoder to current encoder
		set current encoder to encoder "AAC Encoder"
		with timeout of 24 * 60 * 60 seconds
			set convertedtracks to convert tracklist
		end timeout
		repeat with trackn in tracklist
			set enabled of trackn to false
		end repeat
	end if
end tell

Hi, yuanqi. Welcome to the site. :slight_smile:

The reference trick only works with AppleScript lists and the references have to be to the variables containing the lists. For example:

set myList to {very long list} -- Pseudocode.  :)
set myListRef to a reference to myList -- A reference to the variable, not to the list itself.
repeat with i from 1 to (count myList)
	set fred to item i of myListRef
	-- etc.
end repeat

A slightly faster alternative is to write the reference directly into the script instead of storing it in a variable:

set myList to {very long list} -- Pseudocode.  :)
repeat with i from 1 to (count myList)
	set fred to item i of my myList -- NB. 'my' = 'of this script'.
	-- etc.
end repeat

References can’t be made to local variables, so within a handler, you might have to set up your own mini-script in the form of a script object and refer to a property of that:

on myHandler(myList)
	script o
		property ml: myList
	end script

	repeat with i from 1 to (count myList)
		set fred to item i of o's ml
		-- etc.
	end repeat
end myHandler

In your first script, alactrack is set to an AppleScript list containing the tracks returned by iTunes. In your second script, it’s set to the iTunes reference tracks of playlist “Library” whose kind is “Apple Lossless audio file” and enabled is true. With a repeat of the form repeat with trackn in alactrack, trackn is itself a reference to an item of alactrack, so its value isn’t a track, but a reference like item 1 of tracks of playlist “Library” whose kind is “Apple Lossless audio file” and enabled is true, or item 2 of tracks of., depending on the iteration. On both the first two times trackn’s mentioned in the line within the repeat, iTunes searches playlist “Library” for tracks whose kind is “Apple Lossless audio file” and enabled is true and returns a list of qualifying tracks to AppleScript, which then selects the appropriate one. This is obviously slower than getting the list just once and iterating through it directly. The third mention of trackn sets the end of tracklist to that reference, which has to be resolved again twice later in the script.

I haven’t been able to test this, but I believe it’s what you’re trying to do. There may be other ways to speed it up, but this covers the “reference trick”:

tell application "iTunes"
	--construct a list of tracks to be transcoded
	set tracklist to {}
	set alactrack to tracks of playlist "Library" whose kind is "Apple Lossless audio file" and enabled is true
	repeat with i from 1 to (count alactrack)
		set trackn to item i of my alactrack
		if ((count of (tracks of playlist "Library" whose (name is (get name of trackn)) and (time is (get time of trackn)) and kind is "AAC audio file")) = 0) then set end of my tracklist to trackn
	end repeat
	
	if length of tracklist > 0 then
		set currentencoder to current encoder
		set current encoder to encoder "AAC Encoder"
		with timeout of 24 * 60 * 60 seconds
			set convertedtracks to convert tracklist
		end timeout
		repeat with i from 1 to (count tracklist)
			set trackn to item i of my tracklist
			set enabled of trackn to false
		end repeat
	end if
end tell

Just to clarify, “my” basically means a reference to my script’s whatever variable, right?

That’s right. “Me” is the script (or the application running it). If it has a global or property variable called ‘aList’, then aList by itself is a straight use of the variable, while my aList is a reference to it. It’s directly equivalent to what you get when you specify a reference to the variable:

set aList to {1, 2, 3}
set aListRef to a reference to aList
--> aList of «script»