AppleMods

Using Loader

How do I load a module?

In order to load modules, a script must contain a __load__ handler. During the loading process, Loader will call this handler with a single parameter, a ModuleLoader object. The __load__ handler can then call the ModuleLoader’s loadModule command to request a module by name, for example, to load a module named Date:

on __load__(moduleLoader)
    tell moduleLoader
        set _Date to loadModule("Date")
    end tell
end __load__

The loadModule command will return a copy of the Date module (or raise an error if it can’t be found), which can then be stored in a property for use throughout the rest of the script. You can load any number of modules this way, for example:

property _Date : missing value
property _List : missing value
property _Number : missing value
property _Types : missing value

on __load__(moduleLoader)
    tell moduleLoader
        set _Date to loadModule("Date")
        set _List to loadModule("List")
        set _Number to loadModule("Number")
        set _Types to loadModule("Types")
    end tell
end __load__

Note: once underway, the module loading process is entirely automatic; however, it does need to be started ‘manually’. For example, to trigger the loading process when the script is compiled, add the following line below the __load__ handler:

property _ : _Loader's initScript(me)

More on this later.

Where can module files be stored?

During the loading process, Loader will look for module files in several different scopes. Each scope consists of zero or more folders, each of which may contain zero or more module files. There are three scopes in all: embedded, local, and global.

About the embedded scope

Only modules that are saved as a bundle-based script file (.scptd) or applet have an embedded scope. Loader creates a separate embedded scope for each .scptd file it loads. This scope contains a single folder, which is the bundle’s Scripts folder. The path to this folder is determined by Loader and cannot be changed by the user.

By default, the .scptd bundle’s Scripts folder contains a single script, main.scpt. This is the bundle’s main script so Loader will ignore it. However, additional modules may be added to this folder. Modules within an embedded scope can only be accessed by the .scptd’s main script or each other.

About the local scope

The local scope consists of a single folder, which is the folder containing the module file currently being loaded. Loader creates a separate local scope for each (non-global) folder it searches. The path to this folder is determined by Loader and cannot be changed by the user. Modules within a local scope can only be accessed by each other.

About the global scope

The global scope consists of zero or more folders. When loading a module from the global scope, Loader will search all of the scope’s folders until it finds a match. By default, the global scope consists of two folders: ~/Library/Scripts/AppleMods and /Library/Scripts/AppleMods, which will be searched in that order.

Additional folders can be added (the most recently added folder will be searched first); existing folders can be removed. Modules within the global scope can be accessed by any script, subject to OS file permissions. Use the ~/Library/Scripts/AppleMods scope to store modules that you want to be accessible to the current user only. Use the /Library/Scripts/AppleMods scope to store modules that you want to be accessible to any user.

Note that adding/removing folders affects all subsequent module loading operations; therefore, any changes to the global scope’s search paths should be made by the main script’s __load__ handler before loading any modules.

How does Loader search the available scopes?

When the loadModule command is used, Loader will search all three scopes - embedded, local, and global, in that order - until it finds a match.

To restrict the search to a single scope only, use loadEmbeddedModule, loadLocalModule or loadGlobalModule instead.

In all cases, if no suitable module is found then a “Can’t find module...” error is raised.

How do I tell Loader to load my script/applet’s modules?

As mentioned earlier, once a script initiates the loading process, everything else is completely automatic. To initiate the loading process, the script should send Loader an initScript command with a reference to itself as its sole parameter:

_Loader's initScript(me)

Loader will create a ModuleLoader object and pass it to the script’s __load__ handler, allowing the script to load the modules it needs.

Note: only your main script needs to call initScript. Each time the ModuleLoader imports a new module file, it will call the module’s own __load__ handler if it has one, allowing it to load any modules it needs... and so on.

How can I create module loading code for my script/applet?

While you can write module loading code by hand, a simpler solution is to use the LoaderWizard applet provided. Just run it and choose the modules you want loaded, and the appropriate AppleScript code will be placed on the clipboard ready for pasting into your script.

LoaderWizard will automatically list any modules in /Library/Scripts/AppleMods and ~/Library/Scripts/AppleMods.

If you need to load any modules from the script’s special domains, you will need to tell LoaderWizard where the script is first. Just drag-and-drop the script file onto the LoaderWizard icon or click the ‘Choose script’ option and select the script file from there.

If your script needs to use Loader’s more advanced features (see the Loader manual for details), you can use LoaderWizard to generate the initial code and then edit it by hand as needed.