Chapter 20. Dictionaries

In Part II you learned the AppleScript language. It's essential to know this language if you're going to write AppleScript code; yet, ironically, the AppleScript language on its own won't get you very far. That's because AppleScript, all by itself, doesn't do very much; its real power and purpose lies in communicating with scriptable applications, which provide powers that AppleScript lacks. In order that you, the AppleScript programmer, may harness its powers, a scriptable application extends the vocabulary of the AppleScript language. For example, AppleScript can't make a new folder on your hard drive, but the Finder can; therefore the Finder extends AppleScript's vocabulary, supplementing it with terms such as make and folder so that you can use AppleScript to command it (the Finder) to make a folder. This extended vocabulary is called a scriptable application's terminology . A dictionary is the means by which a scriptable application or scripting addition lets the world know how it extends AppleScript's vocabulary.

A dictionary has two audiences—AppleScript and the AppleScript programmer. Let's consider how each of these audiences uses a dictionary:

AppleScript

AppleScript uses an application's dictionary at compile time to look up the terms that the programmer uses. In this way, AppleScript confirms that the terms really exist; as they don't exist within AppleScript itself, AppleScript cannot know without a dictionary that the programmer isn't just talking nonsense. At the same time, AppleScript uses the dictionary to resolve the terms into their corresponding Apple event form; otherwise, it wouldn't know what actual Apple event messages to send to the scriptable application at runtime. And it uses the dictionary when decompiling, to translate those Apple event terms back into English-like words for display to the programmer.

The AppleScript programmer

The AppleScript programmer studies a human-readable display of a dictionary to learn what English-like terms, beyond those built into the AppleScript language itself, may be used when targeting a particular application, or in the presence of a particular scripting addition. Studying a dictionary to figure out how to use AppleScript to get an application to do your bidding is a major part of the typical AppleScript programming experience. Such study must often be combined with experimentation when the dictionary is insufficiently informative.

The dictionary mechanism pervades the life of the AppleScript programmer in several ways:

This chapter discusses all these aspects of dictionaries. See also Chapter 3 for the format in which a dictionary is stored and for the implications when a needed dictionary is missing. See "Target" in Chapter 11, and "Tell" and "Using Terms From" in Chapter 19, for details on how the target is determined, how messages are sent, and how AppleScript decides what application's dictionary it will use to resolve terminology. In Chapter 21 I'll talk more about what scripting additions and their dictionaries add to the mix, and in Chapter 27 we'll actually construct a small dictionary to make an application scriptable. Also, see Appendix A for an example of a real programmer struggling valiantly with a real dictionary.

Example 20-1 exhibits some common patterns of terminology usage. With it, we'll model AppleScript's interaction with dictionaries during the process of compilation.

Compilation of code like Example 20-1 proceeds in two distinct stages:

  1. The tell block causes AppleScript to locate a particular application and load its dictionary.

  2. The terms inside the tell block are resolved.

Let's consider these stages one at a time.

As AppleScript's compiler encounters a tell block (or a terms block) targeting a literal application, it attempts to locate this application and load its dictionary. If the compiler can't find the application, it will ask the user where it is; if the user cancels out of this process, refusing to choose an application, AppleScript will not compile the script (see "Missing External Referents" in Chapter 3).

AppleScript will proceed happily at this point, provided that it can find the application, or the user chooses an application for it—any application. The compiler has not yet reached the stage of trying to resolve any actual terminology, so it doesn't matter whether there is any terminology to resolve, or even whether the application has a dictionary. All that matters so far is that the application referred to in code should be identified with some actual application.

Loading a dictionary takes time, and may even require launching the application in question, which takes even more time. Once the current instance of the AppleScript scripting component has already loaded a particular application's dictionary, however, it doesn't need to do so again, because it now has a copy of the dictionary cached in memory. These are some of the reasons why a script typically takes longer to compile the first time.

Presume that the compiler has reached the interior of the innermost tell block or terms block that caused a dictionary to be loaded. The compiler now proceeds to resolve the actual terms of the block.

Every term used in a given context must be found in a dictionary in order to be resolved. But the innermost application dictionary is not the only place where AppleScript may have to look, because some of the terms may be defined elsewhere. The hunt for terminology thus involves several steps. Here's how it goes:

  1. The commands get and set (and sometimes copy) are specially short-circuited and are not sought in any dictionary.

  2. The term is sought in the innermost application dictionary. (But see "No Terminology Clash," later in this chapter.)

  3. The term is sought in AppleScript's own dictionary (described later in this chapter, under "The 'aeut' Resource").

  4. The term is sought in the dictionaries of any scripting additions that are present.

  5. The term is sought in the script itself.

Let's trace the resolution of the terms in Example 20-1, according to these rules:

  • The term set (and its parameter to) are short-circuited (rule 1).

  • The term folder is defined in the Finder's dictionary (rule 2).

  • The term count appears both in the Finder's dictionary and in AppleScript's own dictionary. The former is used in the present case (rule 2).

  • The term string appears in AppleScript's own dictionary (rule 3).

  • The term display dialog is defined in a scripting addition's dictionary (rule 4).

  • The term c isn't found anywhere, so it's sought in the script, and is resolved as the name of an implicitly defined local variable (rule 5).

As part of the terminology resolution process, AppleScript translates terms into their corresponding four-letter codes and constructs any Apple events that are called for (Chapter 3). So in Example 20-1, the Finder defines folder as 'cfol' and count as 'core\cnte', and AppleScript constructs this Apple event:

core\cnte {
    kocl:'cfol',
    ----:'null'( )
}

The Apple event is written into the compiled code, ready to be sent to the Finder at runtime.