Fabrizio Giudici
Fabrizio Giudici

Reputation: 532

Applescript behaves differently when compiled

This chunk of Applescript:

on collectionToJson(_collection)
  tell application "Capture One 22" to return "{\"name\": " & "\"" & name of _collection & "\", \"id\": " & id of _collection & ", \"kind\": " & "\"" & kind of _collection & "\", \"user\": " & user of _collection & "}"
end collectionToJson

behaves differently when run interpreted and compiled. Output in interpreted mode:

> osascript target/classes/Collections.applescript --byId 14659
{"name": "StoppingDown", "id": 14659, "kind": "project", "user": true}

Output in compiled mode:

> osascript target/classes/Collections.scpt --byId 14659
{"name": "StoppingDown", "id": 14659, "kind": "«constant ****CCpj»", "user": true}

The 'kind' property (which is an enum) is output in a different way. Does it depend on my scarce knowledge of Applescript or on the specific application I'm talking to?

Full script:

on run (_args)
    tell front document of application "Capture One 22"
        set _command to item 1 of _args
        
        if _command is "--byId" then
            set _collection to my findCollectionByIdPath(_args)
            my collectionToJson(_collection)
            
        else if _command is "--byName" then
            set _collection to collection named (item 2 of _args)
            
            repeat with _i from 3 to count of _args
                tell _collection to set _collection to collection named (item _i of _args)
            end repeat
            
            my collectionToJson(_collection)
            
        else if _command is "--children" then
            set _collection to my findCollectionByIdPath(_args)
            tell _collection to my collectionsToJson(collections)
            
        else if _command is "--variants" then
            set _collection to my findCollectionByIdPath(_args)
            tell _collection to my variantsToJson(variants)
        else
            log "Unknown command: " & _command
        end if
    end tell
end run

on findCollectionByIdPath(_args)
    tell front document of application "Capture One 22"
        set _collection to first collection whose its id is item 2 of _args
        
        repeat with _i from 3 to count of _args
            tell _collection to set _collection to (first collection whose its id is (item _i of _args))
        end repeat
        
        return _collection
    end tell
end findCollectionByIdPath

on collectionsToJson(_collections)
    set _result to "["
    set _separator to ""
    repeat with _collection in _collections
        set _result to _result & _separator & my collectionToJson(_collection)
        set _separator to ","
    end repeat
    return _result & "]"
end collectionsToJson

on collectionToJson(_collection)
    tell application "Capture One 22" to return "{\"name\": " & "\"" & name of _collection & "\", \"id\": \"" & id of _collection & "\", \"kind\": " & "\"" & kind of _collection & "\", \"user\": " & user of _collection & "}"
end collectionToJson

on variantsToJson(_variants)
    set _result to "["
    set _separator to ""
    repeat with _variant in _variants
        set _result to _result & _separator & my variantToJson(_variant)
        set _separator to ","
    end repeat
    return _result & "]"
end variantsToJson

on variantToJson(_variant)
    -- FIXME: it seems that this 'tell' slows down a lot
    tell application "Capture One 22" to return ("{\"name\": \"" & (name of _variant) as text) & "\", \"id\": \"" & id of _variant & "\", \"rating\": " & rating of _variant & ", \"colorTag\": " & color tag of _variant & "}"
end variantToJson

Upvotes: 0

Views: 65

Answers (1)

has
has

Reputation: 176

That behavior is normal and to be expected. AppleScript only loads application dictionaries when compiling and decompiling a script. It doesn’t load the dictionary when executing a compiled script because it doesn’t need it.

A compiled script stores application-defined keywords as “four-char codes”, e.g. the keyword project maps to the code CCpj, which AppleScript displays as «constant ****CCpj» when the dictionary definition isn’t available.

While AS can be “forced” to load an application’s dictionary even when it’s not needed (using the run script command to compile a trivial script targeting that application), the obvious straightforward solution is to translate keywords to strings yourself:

to formatKind(aKind)
  if aKind is project then
    return "project"
  else if ...
    ...
  else
    return aKind as string
  end
end formatKind

Or, in your particular case, since you’re running the script via osascript, just keep using the uncompiled form: unlike early System 7 days, where compiling took an appreciable length of time, modern machines are fast enough that it really doesn’t make a noticeable difference to running time.

Upvotes: 1

Related Questions