List of Variables

Please bear with me if the answer to this is obvious…

Is is possible to use a list of variables?

I want to set automatically the value of each variable in a list of variables to a value in a list of values, something like this:

set var_list to {var1, var2}
set value_list to {"1", "2"}
repeat with i from 1 to 2
	set item i of var_list to item i of value_list
end repeat

The problem is that it doesn’t work; from reading the Language Guide I get the feeling that it can’t be done, because lists may contain only values, not variables. Am I wrong?


Perhaps you’re looking for something like this:

set {var1, var2} to {"1", "2"}

Thanks, but I don’t think it’s quite what I want. What I want is to be able to refer to a variable not by its name, but by its position in a list. This would allow me to use a repeat loop to apply the same command to every variable in the list.

I don’t think that can be done. Can you give a real example of why you’d want to do this?


Are you describing an array? You can build records (which a somewhat akin to an array). If you get the properties of things with AS it (usually) returns a record.

For example this is a return from a Finder query: (Note: this is a record NOT an “array”…)

{class:document file, name:“”, index:1, displayed name:“”, name extension:“ai”, extension hidden:false, container:folder “Desktop” of folder “thomasthaden” of folder “Users” of startup disk of application “Finder”, disk:startup disk of application “Finder”, position:{-1, -1}, bounds:{-33, -33, 31, 31}, kind:“Adobe Illustrator Document”, label index:0, locked:false, description:missing value, comment:“”, size:8.8144E+4, physical size:9.0112E+4, creation date:date “Sunday, January 08, 2006 10:16:21 PM”, modification date:date “Sunday, January 08, 2006 10:16:21 PM”, icon:missing value, URL:“file://localhost/Users/thomasthaden/Desktop/”, owner:“thomasthaden”, group:“thomasthaden”, owner privileges:read write, group privileges:read only, everyones privileges:read only, file type:missing value, creator type:missing value, stationery:false, product version:“”, version:“”}

Records do have their own issues but they can be built programatically. (I actually wrote a script this morning to automate building records/arrays.)

Good Luck,
Jim Neumann

For instance: To set properties of tracks of an iTunes list from a text file.

Let’s assume a text file containing the relevant information, one property per line, tracks separated by blank lines, thus


value value ... ...

Using BBEdit to process the file, I create a separate list for each property:

set label_1_list to every line containing (label 1)

this gets a list of lines, and, to make suitable for iTunes, I do a repeat loop through every line to remove the label. Rather than doing a repeat loop for each property, I thought it would’ve been more elegant to do it only once, by placing the repeat loop inside another repeat loop which would go through a list of properties; with the added advantage that more properties could be added to the script simply by adding to this list of properties. Hence the need to refer to variables by position in a list, rather than by name.

Right now, the actual script contains for every property something like this:

set the_label to item 1 of the_string_label_list
set the_length to ((length of the_label) + 1)
set all_artist to contents of (every line whose contents contains the_label)
my the_repeat(all_artist, the_length)

where the_string_label_list is a list containing the labels, and the_repeat is a handler with a repeat loop which cuts off the label from each line. If I want to add a property to processing, I have to add an item to the labels list, and I have to add these four lines (mutatis mutandis) in the appropriate place.

I’m new to records, but they seem to pose the same problem. I see how I can build records from a list

set list_1 to {"1", "2"}
set list_2 to {"a", "b"}

set rec_1 to {p_1:item 1 of list_1, p_2:item 2 of list_1}
set rec_2 to {p_1:item 1 of list_2, p_2:item 2 of list_2}

and I can apply this to the example I’ve given, but how do I do this without knowing how many lists there will be?


If I understand your problem (and I’m not sure I do), I think Bruce Phillips is right. AppleScript does not have a way to call a value from a record using a variable as the name. There are hacks to do it, but they rely on undocumented artifacts in the AppleScript interpreter that easily change with any system update. Since none of us is exactly certain of what you want to accomplish overall, we have trouble getting beyond the assertion that it’s not possible.


Say you use a label like “track number”. You could get the value of this property of a track with ‘run script’. Something like this:

set track_name to “Twain”
set the_property to “track number”
set the_script to “on run p” & return & ¬
“return track number of (item 1 of p)” & return & ¬
“end run”
tell application “iTunes”
set the_pl to first playlist whose name is track_name
set t to first track of the_pl
set track_number to (run script the_script with parameters t)
end tell

Similarly, you could set the property in this manner.

So, you would store labels as strings. Like:

{“track number”, “album”, “artist” …}

and you properties for “track number” might look like this:

{1,2,3,4,1,2,1,2,3,4,5,6 …}

Your overall database of properties might look like this:

{{1,2,3,4,1,2,1,2,3,4,5,6 …}, {“album1”,“album2”, “album3”}, {“artist1”, …}}

To get an item from this database you can just repeat through the label list and find the index.

set label_list to {“track number”, “album”, “artist”}
set this_label to “album”
if this_label is not in label_list then return 0
set c to count label_list
repeat with i from 1 to c
set this_item to item i of label_list
if this_item is this_label then
beep 3
exit repeat
end if
end repeat
return i

Since there are only a limited number of track properties this shouldn’t be too slow, but there are other methods of getting an index of a list item.

Instead of saving your labels in a list, you could store it in a string:

set label_table to "track number album artist "

To get the index of the label “artist”, something like this:

set the_table to "track number album artist "
set o to offset of "artist " in the_table
set r to (o div 10) + 1

Here, the table fields have length 10.


Here’s another way using a list of lists to store label and data:

property my_db : {}
set temp_rec to {label:missing value, data:missing value}
set the_labels to {“numbers”, “alphas”, “bools”}
set the_data to {{1, 2, 3}, {“a”, “b”, “c”}, {true, false, true}}
set c to count the_labels
repeat with i from 1 to c
set label of temp_rec to item i of the_labels
set data of temp_rec to item i of the_data
copy temp_rec to end of my_db
end repeat
– now get the data for label “alphas”
repeat with this_rec in my_db
set d to {}
tell this_rec
if label of it is “alphas” then
set d to data of it
exit repeat
end if
end tell
end repeat
return d

This is ok if there aren’t too many records and you like working with just one main list.


Thanks to everybody who replied. My conclusion is that the answer to my original question is, “No, it can’t be done directly, but there are ways of working around this limitation, if you really have to.”