3.5. Compiled Script Files
A compiled script file is just what you think it is: it's a file containing the bytecode of a compiled script. Unlike text, a compiled script file can be executed without being compiled (because it's already compiled); the runtime engine is fed the bytecode and can leap into action immediately. A lengthy script can take several seconds to compile, so a compiled script file clearly saves some time and overhead when the script is executed. Obviously this architecture is advantageous when the script is not going to change and therefore will not need compiling ever againwhen you distribute the script to others, for example. Applications that act as script runners typically operate on compiled script files (see "Script Runner" in Chapter 2). Script editor applications save a script as a compiled script file by default. When an application has asked the AppleScript scripting component to compile some text, a compiled script file is the only way for the compiled script to outlive that instance of the AppleScript scripting component, which will go out of existence when the host application quits.
(There is actually more to a script, and therefore there can be more to a compiled script file, than the compiled bytecode. I'll discuss these further contents of a compiled script file in "Persistence of Top-Level Entities" in Chapter 8 and "Closures and Stored Script Objects" in Chapter 10.)
You cannot save as a compiled script file code that, for whatever reason, will not compile. This seems tautological, but it can be surprising nevertheless, so it is worth mentioning.
3.5.1. Compiled Script File Formats
To make things more complicated, a compiled script file can come in not one, not two, but three different formats :
Originally there was just one compiled script formatthe resource-fork file . Life was simple: any context that might open a compiled script file in order to run it (technically known as loading the script) could be relied upon to deal with any compiled script file whatsoever. Then when Mac OS X came along, there was a general move to eliminate use of the resource fork everywhere; this resulted in the data-fork file format. Finally, Panther introduced the script bundle format, along with some system functionality that in theory would allow an application to load a compiled script file without worrying about its format.
Two kinds of problem have resulted from this proliferation of compiled script file formats . The first has to do with backwards compatibility. A script bundle can't be opened on any system before Panther (Mac OS X 10.3). A data-fork file can't be opened on most pre-Mac OS X systems. But those are the only two formats that Apple's Script Editor can create, so any compiled script file created by Script Editor will lack some backwards compatibility.
(To be precise about data-fork file compatibility, a data-fork file created by the current Script Editor can usually be opened by Script Editor 1.8.3 on a pre-Mac OS X system. But if you go back any further, to Script Editor 1.4.3which was the standard as recently as the early days of Mac OS 9it won't be able to open it.)
The second problem is that some applications in common use predate the development of one or both of the more recent formats, or for some other reason fail to take proper account of the multiplicity of possible formats. So, for example, Entourage X can't deal with data-fork scripts, and Entourage 2004 can't deal with script bundles. (In fact, iTunes doesn't deal very well with script bundles either.) NSAppleScript (used by Cocoa applications to load compiled scripts) can deal with resource-fork files in Tiger, but couldn't do so in Jaguar (Mac OS X 10.2). This puts the onus on the programmer to make sure the intended script file format will work properly in the particular context where it is to be run, while longing for the good old days when a script was a script was a script.
3.5.2. Run-only Scripts
Normally, a compiled script actually contains two kinds of information:
For example, let's say you put a comment into your script. This comment is nothing that the runtime can execute; that's what it means to be a comment. But clearly you don't want this comment thrown away merely because you compile the script; the compiled script therefore retains it, so that when the script is decompiled, you can still read the comment. Similarly, the names of variables are intended entirely for humans; as far as bytecode is concerned, it would be sufficient to assign them numbers, and that's probably what AppleScript bytecode does. But you want to be able to read your variable names the next time you edit the script, so they are saved as part of the compiled script, even though they aren't needed for execution.
A compiled script can optionally be saved as run-only . (In Script Editor, this option appears as a checkbox in the Save dialog; in Script Debugger, choose File Export Run-Only Script.) In this case, the tokens needed merely to decompile the script and display it to the user are not written into the resulting compiled script file. This makes the compiled script file much smaller and probably causes it to run a bit faster, but it cannot be opened for display or editing.
The usual reason for saving a script as run-only is to keep it from prying eyesyou want to be able to send the script to other people so they can use it, without their being able to read it. There are, however, alternative ways to accomplish the same goal, which may be easier or friendlier. The scripts in an Automator action or an AppleScript Studio application are run-only; but these built products are separate from the original scripts, which remain editable on your machine.