image

Technical Details About Libraries

image

Here are some further technical details about how Script Debugger’s Libraries feature works.

How Libraries Are Attached to a Script

A library file (that is, a script that appears in your script’s libraries pane) is not dynamically loaded every time you run your script. It is reloaded when Script Debugger compiles the script (and when you examine the libraries pane). Those are the only times when Script Debugger cares about where the library file is located on disk (a location that it derives in accordance with your settings in the Relative To pop-up menu in the libraries pane).

The important implication here is this: The mere fact that you change the contents of a library file does not mean that your compiled script that uses the library file will automatically acquire the change. Rather, it is up to you to compile your script that uses the library, as a way of causing any libraries it uses to be reloaded. Luckily, compilation happens any time you alter your script and then run it; or, if your script hasn’t been altered and doesn’t need compilation, you can force it to be compiled (and therefore to reload its library files):

image

Once loaded, a library is (invisibly) present as part of your compiled script. The resulting compiled script file can be executed in any script runner environment. (But to edit it in another script editing environment without flattening it first will probably cause the invisibly present library to be stripped out.)

Duplicate Library Definitions

Unlike AppleScript’s load script command, top-level entities of a library file effectively become top-level entities of your script. In theory, this means that their names can clash with other top-level entities. For example, if a library file contains a top-level handler howdy(), and if your script already has (or you eventually give it) a handler named howdy, you’ve got two top-level things named howdy, and that’s illegal.

Script Debugger helps you with this situation. If you try to compile a script where there’s a name conflict between libraries or between a library and the main script, Script Debugger puts up a dialog warning you of the problem (“The following duplicate library definitions have been found”). You won’t be able to compile the script under these circumstances.

Such a name conflict includes the existence of two run handlers. In other words, given that you have a library file (or more than one library file) plus the main script, only one of those may contain top-level executable code, because such code constitutes an implicit run handler, and you can’t have two run handlers in a script.

An Obscure Top-Level Entity Bug

There’s a bug in AppleScript that can cause a top-level entity in your main script to be confused with a top-level entity in a library. For example, suppose your library file goes like this:

    property x : "hello"
    on greet()
        display dialog x
    end greet

And suppose your main script goes like this:

    property y : "goodbye"
    greet()

When you then execute your script, the resulting dialog says “goodbye”, not “hello”, even though greet refers to x (“hello”) and no code anywhere refers to y (“goodbye”). The reason is that AppleScript has confused x with y.

A safe approach is this: if a script is to be used as a library file, wrap the whole script up in a script object, like this:

    script myLibrary
        property x : "hello"
        on greet()
            display dialog x
        end greet
    end script

That way, when the library is loaded, what’s loaded is a single object — the script object. The script object keeps the namespace clean, preventing name confusions. (In the example above, the way to refer to x in your script would be as myLibrary's x, and the way to call greet() in your script would be to say tell myLibrary to greet().)

Another solution is not to have a property declaration and a handler definition in the same library file, thus avoiding the situation that triggers the bug.