This module allows you to write Perl code in object-oriented syntax to control Mac applications. The module does not actually execute Apple Events, but actually translates Perl code to AppleScript code and causes it to be executed.

If you need to get a particular element of an object, put the identifier as an argument to the thing that names the element list:

my $window = $finder->windows(1);

If you need to specify parameters of a command, use a hash for the parameters, where each key/value pair corresponds to a parameter name and value:

my $epson_files = $finder->files(whose_name_contains => 'epson');

You can specify both identifiers and parameters:

my $epson_files = $finder->files(1, whose_name_contains => 'epson');

Finally, there are cases where you need to create an object reference, rather than obtaining one from an application. To do this, you can use an application object to create a Mac::AppleScript::Glue::Object(3pm) that refers to both the object reference and the application to which that reference should belong:

my $folder = $finder->objref('folder "Applications"');

Then, you can use that as you normally would:

# open the "Applications" folder
$folder->open;

If you don't need a full-fledged object, you can simply specify a parameter of a reference to a scalar containing a string:

If you issue a statement that will return a value, like insertion location, the result of that statement is always a scalar. The actual contents of this scalar depends on the sort of statement. It will be one of:

When Mac::AppleScript::Glue(3pm) sees this sort of reference, it puts the whole object reference string into an object of type Mac::AppleScript::Glue::Object(3pm) (see Mac::AppleScript::Glue::Object). It also stores in this object the application object that created the object. By doing this, the Mac::Application::Glue::Object(3pm) can be used by itself to access or modify other data.

If the statement returned an AppleScript "list" or "record", the result will be a Perl array- or hash-reference, respectively. This could contain simple scalars, or a combination of any of the result types; it can also be nested.

Note that you'll have to dereference the references to use the elements:

For multi-word AppleScript terms like insertion location, use the underscore character (_) in place of each space character.

You generally need to reverse the parts of a statement when translating AppleScript to Perl. In AppleScript, open insertion location really sends the "open" message to the object represented by "insertion location". This maps to the Perl syntax insertion_location->open().

Unlike Perl, AppleScript makes a distinction between booleans and numbers -- you can't intermix them. So if an AppleScript method wants a boolean as a parameter, you must use the AppleScript constants true or false. You can do this by enclosing the string with angle-brackets (<true>) or passing a reference to a string containing the constant (\'true').

The resulting AppleScript is executed by the Mac::AppleScript(3pm) module (by Dan Sugalski); any results are returned as text.

The AppleScript-format result data is translated into into Perl data structures as appropriate.

Perl's $AUTOLOAD feature (perlobj) is used to translate statements like $finder->insertion_location to AppleScript. Method calls that aren't defined in the module itself and don't refer to a part of the object's data structure are delegated to a translater function that tries to write the method as if it was AppleScript.

AppleScript's concept of the "object reference" is essential to the idea of having Perl objects for things other than applications.

The AppleScript interpreter seems somewhat lenient on the exact syntax of the language. This makes it possible to write AppleScript statements that work even though they look weird.

Parses a string containing an AppleScript result, and returns the Perl data structures corresponding to that result. If $app is specifed as a Mac::AppleScript::Glue::Application(3pm) object, any object references will be "owned" by that application.

Provides a nicely-formatted view of any object. The object can be as simple as a regular scalar, or a deeply-nested tree of references. If the object is a Mac::AppleScript::Glue::Object, angle-brackets (<, >) are placed around its value.

If a string is supplied as $label, the output will be labeled suchly.

Output is to STDERR by default; you can provide an alternate filehandle in $fh if you like.

Show each generated AppleScript before it's sent off to the script interpreter, as well as the AppleScript-formatted result string. This is useful when writing programs using Mac::AppleScript::Glue, as looking at the generated AppleScript is often the best way to figure out why a statement is failing.

Unfortunately this package doesn't mean that you don't have to know AppleScript, or the class/event hierarchy of the operating system. Both of those can be quite inscrutable.

I recommend having the Script Editor program open while writing Perl code. Use the dictionary browser (File menu > Open Dictionary) to browse the dictionaries for the applications you're trying to control. If you're having trouble getting the right Perl code written, try writing it in AppleScript first, then translate to Perl, then let this module translate it back to AppleScript. ;)

If you're trying to navigate through inscrutable AppleScript results, try using the dump_pretty() function (see above).

Finally, turn on the SCRIPT and RESULT debugging keywords for the most useful yet not-too-overwhelming debug output.

It's fairly slow. This is mostly because a compound statement ($finder->insertion_location->name) requires several separate AppleScript executions, generally one per element besides the application object. It's also slow because under the hood, the Perl calls are translated to AppleScript, then compiled, and finally executed.

Error-handling is nearly non-existant. If the resulting AppleScript is bad, or the target applications don't understand the resulting AppleScript, this module will force a die(), and you will see errors on STDERR. If you want to trap this, use eval.

AppleScript generation is not quite right. However, it works most of the time.