Record Confusion - Why is it so


(Peter Arnold) #1

Hi all, am a relative newbie to AppleScript, but not programming. I am having trouble understanding why the following script does not work as expected …

– Script –
– Scrip Editor Version is 2.9
– Applescript appears to be version 1.0
– OSX Version 10.12.6
– LN Script Debugger Version 6.0.5
– The image is a photo - so any image and path to a photo should work.

use framework "Foundation" -- useful for getting to objC structures 
use scripting additions -- Required if using "use" and shell scripts, and other scripting extensions

set theFile to "/Volumes/scratch/images/scripts/working_scripts/test_image2.JPG" as «class furl» -- fixes a bug in Applescript file handling - required when using "use"
set pathList to quoted form of POSIX path of theFile

set recInfo to (info for theFile as alias) as record
set DummyRec to {a:"a", b:"b"}
set testRecord to (recInfo & DummyRec)

on KeysOfRecord(rec)
	set ca to current application
	return (ca's NSDictionary's dictionaryWithDictionary:rec)'s allKeys() as list
end KeysOfRecord

set keyList to KeysOfRecord(recInfo)


Script Debugger’s variable display lists
recInfo as a record with 20 entries
DummyRec as a record with 2 items
testRecord as a record with 22 items

If I use set keyList to KeysOfRecord(recInfo) – keyList is a list with zero entries - I expected 20
If I use set keyList to KeysOfRecord(DummyRec) – keyList is a list with 2 entries - I expected 2 - works
If I use set keyList to KeysOfRecord(testRecord) – keyList is a list of 2 entries - I expected 22

I would appreciate any help in understanding
a) Why this script does not work as I expect
b) How do I fix it (reliably getting file record keys appears to be nearly impossible with AppleScript).


(Shane Stanley) #2

Welcome to the arcane world of AppleScript records.

The short version: if a label is an AppleScript keyword or a property declared in terminology, as you’ve seen the value gets lost in conversion to a dictionary.

The longer version is that AppleScript records are smoke and mirrors: they look a bit like dictionaries, but under the hood they’re entirely different. The values that disappear are in fact stored in a list of AppleEventDescriptors – the label you see simply reflects the descriptor type. An extra descriptor of user record fields (type usrf) contains a list of alternating labels and values for any user entries.

But given that info for is deprecated (not that that necessarily means a lot – it’s been that way for a long, long time), you can always use AppleScriptObjC instead. So something like either of these:

set {theDict, theError} to current application's NSFileManager's defaultManager()'s attributesOfItemAtPath:thePath |error|:(reference)


set theURL to current application's |NSURL|'s fileURLWithPath:thePath
set {theDict, theError} to theURL's resourceValuesForKeys:{current application's NSURLHasHiddenExtensionKey, current application's NSURLIsDirectoryKey, current application's NSURLIsHiddenKey, current application's NSURLIsPackageKey} |error|:(reference) -- add keys as required

(Peter Arnold) #3

Hi Shane,

Thanks for the info. Hmm “Info For” is already deprecated. In all my research I did not notice this anywhere.
My observation is that information on AppleScript is smeared across a large number of documents, books and brain cells of people who spend a lot of time with it.
Could be made a hell of a lot easier for interested persons to learn and master as it seems to be very powerful on a mac environment - but I guess I say that almost every time I go through a learning curve with a new language.

I will try what you suggest and see if I can get it to work. Thanks again for the information.


(Shane Stanley) #4

It’s hidden in plain sight: the dictionary description says:

This command is deprecated; use ‘tell application "System Events" to get the properties of …’

But as I said, it’s been like that for a very long time.

One of the problems is that there are two things that are closely related but not the same: the AppleScript language, and how it’s implemented. Unfortunately implementations differ, often wildly.