Changing name to a record /Dynamically set the name of a record

hi all,

It is possible to dynamically name a list?
If I want to build a list of records, and name it based on a dynamic name, is that possible?

I am building a list of record using:

set Bill to {a:1, b:2, c:3}
set Marc to {a:1, b:2, c:3}

-- Below I am making a list of records, using a pre-defined name for the list ("SuperList")
-- So, the list is named "SuperList", and it contains 2 records (named Bill, Marc)
set SuperList to {Bill:Bill, Marc:Marc}

--making. a list of records, using a dynamic name
repeat with x from 1 to 3
	set DynamicListName to "List_" & (x as text)
	set DynamicListName to {Bill:Bill, Marc:Marc}
	-- in the above line the "DynamicListName" as text is used for the  listname, rather that its content (List_1, List_2, etc..)
end repeat

is it possible to use “DynamicListName” value rather that its name?

Hi. You can easily build a record from values.

(run script "{|" & ("FinalName") & "|: " & (quote & ((current date)'s time) & quote) & "}")

Are you sure what you posted is what you want? There’s no record involved in your final statement.

(It’s also very confusing the way you’ve named your keys theValues and your values theKeys.)

Sorry for the confusing post #1.
I have simplified it a lot, going straight to the point: is it possible to build a list using a dynamic name?

I presume you mean a record, not a list. You can use Marc’s code, or you can use the code you deleted, which used dictionaryWithObjects:forKeys:, and coerce the result to a record.

I might miss something obvious here. And I am sorry for that, … but:

set ListName to "ActualTime_" & (time of (current date)) --> "ActualTime_59935"
set ListName to {1, 2, 3} -- I get a list which name is "ListName" and contains {1,2,3}, but I want a list which name is "ActualTime_59935" and it contains {1,2,3}

In the above code I want a list which name is NOT “ListName”, but actually the content of ListName variable (= “ActualTime_59935”)

So you want to create a variable name at run time? May I ask why?

Technically, a record doesn’t have a name to be changed—dynamically or otherwise. You can assign a variable or key(s) to facilitate calling the item. You can also build a record from scratch. Observe the following results in the editor, as I think you’re trying to do some variation.

#1) concatenate
set firstRec to {Bill:{hair:"hairlike", eyes:2}}
set secondRec to {Marc:{hair:"shiny", eyes:2}}
set recordVar to (run script "{ObservationTime:" & ((current date)'s time) & "}") & firstRec & secondRec
--return recordVar -->(*ObservationTime:69595, Bill:hair:hairlike, eyes:2, Marc:hair:shiny, eyes:2*)

#2) edit after cloning
copy recordVar to nextVar
set nextVar's Bill's hair to "balding"
return nextVar --> 	(*ObservationTime:69630, Bill:hair:balding, eyes:2, Marc:hair:shiny, eyes:2*)

Hi Shane,
Indeed this was my question: “create a variable name at run time”.

I am making a catalog of information on selected files. Those are my steps:
#1 grab the selected files (in Finder);
#2 extract some info (filename, some of the metadata, file size);
#3 if the info match some criteria, then build a list (which name is “ListOfFilesMatchingCriteria”), such as:

its Metadata
its filesize
Item 2
its Metadata
its filesize

But instead of having item1 (Item2, …), I would like to name this sub-list using is “real” filename, so the structure should be:

its Metadata
its filesize
its Metadata
its filesize

Most likely using a variable name not defined up-front is impossible or is a bad idea. So I can use the structure of the first type of list. I just tought the the second structure is more compact and more elegant. And this was an excuse to learn something new …

The solution to that is to use records rather than lists.

Thanks Marc and Shane.

I also wanted to learn from this thread. So, just to make sure I understood the basics, I wrote the following, which uses the approach given by Marc Anthony in post 2:

set aPropertyLabel to "labelOne"
set aRecord to run script "{|" & aPropertyLabel & "|:\"a\", labelTwo:2}"
labelOne of aRecord --> "a"
labelTwo of aRecord --> 2

The above script worked but the following did not:

set ListName to "ActualTime_1"
run script "set |" & ListName & "| to {1, 2, 3}"
ActualTime_1 --> error "The variable ActualTime_1 is not defined."

The following doesn’t work either, so perhaps this has nothing to do with variable names and is attributable to how I’m using the run script command.

run script "set aVariable to {1,2,3}"
aVariable --> error "The variable aVariable is not defined."

run script will execute a script in a separate AppleScript instance. Therefore, it won’t have access to any of the variables you define in your main script.

AppleScript identifiers can’t be created or modified at run time, without creating a separate AppleScript instance. Even then, this trick will let you generate identifiers that belong to some parent data structure (i.e. properties in a record), but it won’t give you access to anything at the top-level.

Once you’ve created a record with on-the-fly property names, you are then faced with the problem of how another part of your script then references these property names. If it already knew what the identifiers were going to be, you wouldn’t have needed a trick to generate them; if you didn’t know ahead of time, then you will have to perform another similar manoeuvre every time your script needs to retrieve a property from that record.

There are legitimate, worthwhile instances where one needs to create a record with custom property names during run time. Probably the best way to do so would be:

(current application's NSDictionary's dictionaryWithObjects:{2, "3"} forKeys:{"a", "b"}) as record
    --> {a: 2, b: "3"}

A slightly hack-y way, but marginally less so than run script is:

set f to "/tmp/reco"
close access (open for access f)
set eof of f to 0

write  {«class usrf»:{"a", 2, "b", "3"}} to f
read f as "reco" --> {a: 2, b: "3"}

A third way would involve property lists.

If you really need to have variable names generated on the fly (and I can’t think why one would), you’ll have to create your AppleScript on the fly, which is probably then best done via the command line, then executed using osascript, otherwise you’ll be creating and destroying AppleScript instances all over the place, which feels a bit wasteful.

Thanks CK for the excellent response. It took some study but I understood most of your post. That which I didn’t understand will require more learning, but I have lots of time for that. Thanks again.

You are most welcome. Let me know if there’s anything I didn’t explain clearly enough, and I’ll do my best to rephrase.