The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Mac::Glue - Control Mac apps with Apple event terminology

SYNOPSIS

        use Mac::Glue;
        my $glue = Mac::Glue->new('Finder');
        $glue->open( $glue->prop('System Folder') );
        # see rest of docs for lots more info

DESCRIPTION

"Mac::Glue does AppleScript so you don't have to."

You should have the latest cpan-mac distribution:

        http://sourceforge.net/projects/cpan-mac/

For more information, support, CVS, etc.:

        http://sourceforge.net/projects/mac-glue/

Mac OS apps speak to each other with a lingua franca called Apple events. The most common way to do Apple events (aside from doaing them in a precompiled application with C, Pascal, etc.) is with AppleScript. Other languages can do Apple events too, like Frontier and even Python. But we like Perl.

MacPerl has for a few years had an interface to Apple events, with the Mac::AppleEvents module, which is the basis for everything we'll do here. Mac::AppleEvents::Simple was made to simplify the process of doing Apple events in MacPerl, but even that can be too much trouble to use. One has to find out the class and event IDs, find out the keywords and data types for each parameter, etc.

So the vision was born for a framework that wouldn't take much significant work. An application's AETE resource would provide the names to match to the cryptic four-character codes we had been using. Compare.

Raw Mac::AppleEvents method
        use Mac::AppleEvents;
        $evt = AEBuildAppleEvent('aevt', 'odoc', typeApplSignature, 'MACS',
                kAutoGenerateReturnID, kAnyTransactionID,
                "'----': obj{want:type(prop), from:'null'()," . 
                "form:prop, seld:type(macs)}"
        ) or die $^E;
        $rep = AESend($evt, kAEWaitReply) or die $^E;
        AEDisposeDesc($evt);
        AEDisposeDesc($rep);
Easier Mac::AppleEvents::Simple method
        use Mac::AppleEvents::Simple;
        do_event(qw(aevt odoc MACS),
                "'----': obj{want:type(prop), from:'null'()," . 
                "form:prop, seld:type(macs)}"
        );
Cool Mac::Glue method
        use Mac::Glue;
        my $glue = Mac::Glue->new('Finder');
        $glue->open( $glue->prop('System Folder') );

The latter is much simpler to understand, to read, to write. It leverages the user's understanding of AppleScript. And it is just more natural.

There are downsides. Mac::Glue is less powerful than the Mac::AppleEvents raw interfaces, because it offers less flexibility in how events are called. It is also slower to start a script, because the glue structures need to be loaded in. However, once a script has started, a difference in speed from the raw interfaces should be minimal (though not a lot of testing has been done on that). With the code above, on a PowerBook G3/292, running Mac OS 8.6:

    Benchmark: timing 100 iterations of glue, glue2, raw, simple...
          glue: 10 secs ( 9.98 usr  0.00 sys =  9.98 cpu)
         glue2:  8 secs ( 8.35 usr  0.00 sys =  8.35 cpu)
           raw:  8 secs ( 7.88 usr  0.00 sys =  7.88 cpu)
        simple:  7 secs ( 7.50 usr  0.00 sys =  7.50 cpu)

The "glue2" entry is the same as "glue" entry, but it creates a glue object only once instead of each time through, cutting down on the overhead. It appears that Mac::Glue is a bit slower than the other methods, but not substantially, and it is cooler and easier. The one place where performance is the biggest problem is on initial execution of the program, but once it starts it is plenty fast. We'll work to cut down that start time, too.

So, now that you are convinced this is cool, let's continue.

Creating a Glue

In order to script an application with Mac::Glue, a glue must be created first. For that, the application is dropped on the gluemac droplet. A distribution called Mac::AETE, created by David Schooley, is used to parse an application's AETE resource, and the glue is written out to a file using Storable, DB_File, and MLDBM. Glues are saved in $ENV{MACGLUEDIR} (which is defined when Mac::Glue is used if it is not defined already). By default, glues are stored in :site_perl:Mac:Glue:glues:.

All glues have access to the global scripting additions and dialect information. Glues for these must be created as well, and are created with the gluescriptadds and gluedialect programs, which are similar to the gluemac program. They are saved in "$ENV{MACGLUEDIR}additions:" and "$ENV{MACGLUEDIR}dialects:".

Along with the glue file is a POD file containing documentation for the glue, listing all the events (with parameters), classes (with properties), and enumerators, and descriptions of each.

Using a Glue

The first thing you do is call the module.

        use Mac::Glue;

Then you create an object for your app by passing the new function the name of the glue (you may include or omit underscores in the name if you like).

        my $glue = Mac::Glue->new('My App');  # or My_App

You can also pass in additional parameters for the type of target to use. For PPC ports, you can do this:

        my $glue = Mac::Glue->new('My App', ppc => 'My App Name',
                'Server Name', 'Zone');

You may also specify a process serial number:

        my $glue = Mac::Glue->new('My App', psn => $psn);

Note that $psn should be a regular long integer, and will be packed into a double long behind the scenes. If this confuses you, don't worry about it; the values returned from the Mac::Processes module are good to pass back in as $psn.

You can also pass a path to an application:

        my $glue = Mac::Glue->new('My App', path => $path_to_file);

New for Mac OS 9, you can send events over TCP/IP:

        my $glue = Mac::Glue->new('My App', eppc => 'My App Name',
                'some.machine.com');

Also, the address can be changed after the fact:

        my $glue = Mac::Glue->new('My App');
        $glue->ADDRESS(eppc => 'My App Name', 'some.machine.com');

Once you have your glue set up, you start calling events, as they are documented in the POD file for the glue. The events can be called case-insensitively, with the exception of those that match the names of the special methods (see "Special parameters and methods"). In that case, since the special methods are in all caps, the event methods can be called case-insensitively except for all caps. e.g., for an event named reply, it could be called with:

        $glue->Reply;
        $glue->reply;
        $glue->RePLY;

However, it could not be called with $glue->REPLY, since that is reserved.

All applications respond to events differently. Something that works for one application might not work for another, so don't use any of these examples as a way you should script a specific application. They are just hyopthetical examples, for the most part.

Events sometimes accept parameters, sometimes they don't. The primary parameter of most events is a special parameter called the direct object parameter. In your event call, pass the data for that parameter first:

        $glue->open($file);

Other parameters must be named and must be provided as key-value pairs, with the key as the name of the parameter, and the value as the parameter's data:

        $glue->open($file, using => $myapp);

Note that the direct object parameter is the only parameter that doesn't need a name in front of it, and must come first in the list if it is supplied at all.

Mac::Glue will attempt to coerce passed data into the expected type. For example, if open expects an alias, the file specification in $file will be turned into an alias before being added to the event.

You can override this behavior with the param_type function. If open expects an alias (typeAlias), but you want to pass text, you can do:

        $glue->open( param_type(typeChar, $path) );

Each datum can be a simple scalar as above, an AEDesc object, an Mac::AEObjDesc object (returned by obj, prop, and event methods), an Mac::AEEnum object (returned by the enum function), or an array or hash reference, corresponding to AE lists and records. In this example, we nest them, with an arrayref as one of the values in the hashref, so the AE list is a datum for one of the keys in the AE record:

        $glue->make(new => 'window', with_properties =>
                {name => "New Window", position => [100, 200]});

The words "name" and "position" will be changed into the proper corresponding AE IDs. And on return, record keys will be changed back from the AE IDs into the English words.

Events return direct object parameters, turned into suitable data for use in the program. Aliases are resolved into file specifications, AE records and lists are turned into Perl hashes and arrays (recursively, for nested lists), etc.

        my @urls = $sherlock->search_internet('AltaVista',
                'for' => 'Mac::Glue');

AE objects (which will be discussed later) are returned as Mac::AEObjDesc objects, so they may be used again by being passed back to another event.

        my $window_object = $glue->get( window => 1 );
        $glue->save($window_object);

This allows AppleScript-like loops:

        my @selection = $glue->get( $glue->prop(selection => of => window) );
        my @owners;
        for my $item (@selection) {
                push @owners, $glue->get( $glue->obj(cell => 'Owners' => $item) );
        }

Some objects may allow an easy way to get a human-readable form, with the as parameter:

        my $item = $glue->get( file => 1, as => 'string' );

Errors are returned in the special variable $^E, which should be checked immediately after an event call.

        $glue->close(window => 1);
        if ($^E) {
                warn "Couldn't close window: $^E\n";
        }

Or, if a value is expected and none is returned:

        my $file = $glue->choose_file('Select a file, please.')
                or die "No file chosen: $^E";

Checking $^E only works if the error returned is an error number. If it isn't, the actual error is available from the reply event, which can be accessed by using the RETOBJ parameter (described below in "Special parameters and methods").

You can also handle errors with the ERRORS handlers (also described below in "Special parameters and methods").

Creating object specifier records

This is one of the more complex parts of Apple events, and it is only partially implemented (though full implementation is expected eventually, and most of it is implemented now).

Object specifier records are created by the obj method, and have four components to them.

class
container
form
data

The class and data are passed as key-value pairs, like in AE records or parameter lists. The form and the type of the data are determined by the glue data or a good guess. The container is determined by the order of the key-value pairs: each pair is contained by the pair or object that follows it.

        my $obj = $glue->obj(file => 'foo', folder => 'bar', disk => 'buz');

So you have three pairs. The key of each pair ("file", "folder", "disk") is the class. The value of each pair ("foo", "bar", "baz") is the data. Because the data are each text, the form defaults to formName, and the data type defaults to typeChar (TEXT). If the data is a number, then the form would be formAbsolutePosition, and the data type would be typeLongInteger.

So that leaves only the container. Each pair is contained by the pair following it. The disk contains the folder, the folder contains the file. The disk has no container (its container is null).

Easy, right? I hope so. That's the idea. But let's go back to the forms, since that is the only tough part left.

The primary forms are types, names, unique IDs, absolute positions, relative positions, tests, and ranges. Normally, text data has form name and type TEXT. Integer data has absolute position form, and integer type. The obj_form function accepts three parameters, which allows you to set the form and data, or form, type, and data, in case you want to send data different from how Mac::Glue would guess.

These two are the same, since in the second case, the other is assumed:

        use Mac::Glue ':glue';

        $obj1 = $glue->obj(window =>
                obj_form(formAbsolutePostion, typeLongInteger, 1));

        $obj2 = $glue->obj(window => 1);

Special constants are exported that specify relative positions and absolute positions.

        $first  = $glue->obj(file => gFirst, property => 'Desktop');
        $second = $glue->obj(file => gNext, $first);

        for ($first, $second) {
                print $glue->get($_, as => 'string');
        }

of and in are synonyms of property:

        $glue->obj(file => gFirst, property => 'Desktop');
        $glue->obj(file => gFirst, of => 'Desktop');
        $glue->obj(file => gFirst, in => 'Desktop');

The "as" parameter above has a form of type, such as:

        obj_form(formPropertyID, typeType, 'string');

Then "string" is turned into a four-character ID behind the scenes (in this case, it is "TEXT").

A special method called prop is for specifying properties. These are equivalent:

        $glue->obj(property => 'Desktop');
        $glue->prop('Desktop');

Descriptor types for object specifier records

Property IDs

Normally, the glue will know a property is expected and coerce whatever string you provide into its four-character ID. Sometimes obj_form(formPropertyID, typeType, 'property_name') may be appropriate.

Name

Just pass the data as text. If there is some ambiguity, you may explicitly use obj_form(formName, typeChar, 'string').

Unique IDs

Could be anything.

Absolute position

As discussed above, if it is an index number, you can just pass the number, as in window => 1, or you can explicitly mark it with window => obj_form(formAbsolutePosition, typeLongInteger, 1).

For other absolutes, you may use constants, such as window => gLast. Choices are gFirst, gMiddle, gLast, gAny, gAll.

These are just shortcuts for explicit forms like obj_form(formAbsolutePosition, typeAbsoluteOrdinal, kAEAll).

Note that if there is a plural form of the class name, you may use it to mean the same thing as "class => gAll". These are all the same:

        $f->obj(files => of => 'System Folder');
        $f->obj(files => gAll, of => 'System Folder');
        $f->obj(file => gAll, of => 'System Folder');
Relative position

Similar to absolute position, but an additional object must be specified, such as file = gNext, file => gMiddle>, which would return the file after the middle file. Available constants are gNext and gPrevious.

The explicit form is obj_form(formRelativePosition, typeEnumerated, kAENext).

Ranges

The range function accepts two arguments, the start and stop ranges.

        range(START, STOP)

Each can be a number index, an absolute position constant, a string, or another data type passed with obj_form. Here are a few ways to specify files in the System Folder:

        $f->obj(files => range(1, 5), of => 'System Folder');
        $f->obj(files => range(1, "System"), of => 'System Folder');
        $f->obj(files => range("Finder", "System"), of => 'System Folder');
        $f->obj(files => range(gFirst, "System"), of => 'System Folder');
Whose tests

The whose function accepts either logical records or comparison records.

        # comparison record
        $f->obj(CLASS => whose(CLASS => VALUE, OPERATOR, VALUE));
        $f->obj(CLASS => whose(PROPERTY, OPERATOR, VALUE));

PROPERTY and CLASS => VALUE work like prop() and obj(). The PROPERTY form is the same as property => VALUE.

OPERATOR is contains, equals, begins_with, ends_with, l_t, l_e, g_t, or g_e. VALUE is the value to compare to.

        # files whose name begins with "foo"
        $f->obj(files => whose(name => begins_with => 'foo'));

        # rows whose first cell equals "bar"
        $f->obj(rows => whose(cell => 1 => equals => 'bar'));

Then there is the logical record type, for use when more than one comparison record is needed.

        # logical record
        $f->obj(CLASS => whose(OPERATOR, LIST));

OPERATOR is AND, OR, or NOT. LIST is any number of other logical records or comparison records, contained in anonymous arrays. So you can join any number of records together:

        # words where it contains "e" and it begins with "p" and it does not end with "s"
        $aw->obj(
                words => whose(AND =>
                        [it => contains => 'e'], [it => begins_with => 'p'],
                        [NOT => [it => ends_with => 's']]
                ), $text)

Note how each logical record and comparison record following each logical operator is in an anonymous array. Also not how the special word "it" refers to the object being examined.

There's one more record type that works similarly to the above object specifier records, but is not exactly the same thing. It's called an insertion location record, and is created like this:

        location(POSITION[, OBJECT])

POSITION is a string, and can be one of before, after, beginning, or end. front is a synonym for beginning, and back and behind are synonyms for after.

OBJECT is the object to be positioned against, and will be the null object if not supplied.

        my $aw = new Mac::Glue 'AppleWorks';
        my $text = $aw->prop(text_body => document => 1);
        $aw->activate;

        # note null object in location()
        $aw->make(new => 'document', at => location('front'));
        $aw->set($text, to => "foo bar buz baz.");

        $aw->move(
                $aw->obj(word => 4 => $text),
                to => location(after => $aw->obj(word => 2 => $text))
        );

Special parameters and methods

Special parameters can be passed in the event which control certain aspects of the event call's behavior. They can be passed as parameters (affecting only the one event), or called as methods (which affect every call made from that object). They are all upper case.

        $glue->REPLY(1);                # wait for reply on all events
        $glue->close(REPLY => 0);       # don't wait for this one event
REPLY

Boolean, for whether or not to wait for a reply. Default is to wait.

MODE

Set other modes, such as kAENeverInteract. This value is OR'd together with the REPLY value. Default is kAECanInteract | kAECanSwitchLayer.

SWITCH

Switch to the application being called. Usually more efficient to use the activate event:

        $glue->activate;
PRIORITY

Set the event priority. Default is kAENormalPriority.

TIMEOUT

Number of seconds to wait before timing out. Default is a couple hundred thousand seconds or so.

RETOBJ

Boolean, for whether or not the event call will return the direct object data (the default), or a Mac::AppleEvents::Simple object, containing references to the actual event and reply, so you can do more advanced things with the data if you want to.

ERRORS

A subroutine reference that will handle any errors (that is, will be executed only if $^E is true) after the event is executed. Your handler will be passed 6 or more arguments:

        0       The glue object
        1       The event object (same object returned by RETOBJ)
        2       The Glue's name
        3       The event's name
        4       The error message
        5       The error number
        6..n    Any arguments passed to the event in the first place

Example:

        sub error_handler {
                my($glue, $event, $gluename, $eventname,
                        $errs, $errn, @args) = @_;
                my $args = join ', ', @args;
                die "$gluename->$eventname($args) event failed:\n$errs\n";
        }

        $finder->open(
                $finder->obj( item => 'HD' ), # nothing named HD in Finder
                ERRORS => \&error_handler
        );

Result:

        # Finder->open(DOBJ, Mac::AEObjDesc=HASH(0xc4c0814)) event failed:
        No such object (OS error -1728)

Editing a Glue

There is an included droplet, glueedit, for editing glues. Drop a created glue on the droplet, and it will make a text file on the Desktop. Edit it, and then drop the text file back on the droplet. Be careful; this obviously can be dangerous. If you break something, you can use gluemac to recreate the original glue, of course.

Why would you edit a glue? Well, sometimes AETE resources are wrong. :)

EXPORT

Mac::Glue has two export sets. glue exports the constants and functions beginning with "glue" listed in "Creating Object Specifier Records", as well as the functions obj_form, enum, location, range, and whose. all exports everything from Mac::AppleEvents and Mac::AppleEvents::Simple, including all functions and constants. Nothing is exported by default.

        use Mac::Glue ':glue';  # good for most things
        use Mac::Glue ':all';   # for more advanced things

TIPS

Hide background apps

  use Mac::Glue;
  use Mac::Apps::Launch;
  $a = new Mac::Glue 'Acrobat Exchange';
  $a->launch;
  Hide($a->{ID});

  # now do your thing ...

Scripting Addition Maintenance

If you have a lot of scripting additions, it can slow down Mac::Glue (on startup) and take up more RAM. Same thing goes for Mac OS in general; each installed additions takes up more RAM and has to be loaded into the system, taking up extra time. So only keep installed the ones you want installed.

If you have a huge scripting addition and you only want to use a small part of its functionality, you could also edit the glue and strip out portions you don't want. This is not recommended for those who don't know precisely what they are doing, and the gains may be unnoticable anyway.

GOTCHAS

  • MAKE SURE site_perl COMES FIRST IN YOUR LIBRARY PREFERENCES. Thank you. :-)

  • Do NOT send an event to the MacPerl application itself and expect a reply. Instead, try $macperlglue->REPLY(0). Similarly, do not drop MacPerl onto gluemac. Instead, you can make a copy of the MacPerl application, and drop that on gluemac.

  • You should have the latest cpan-mac distribution is installed.

  • You should delete old dialect glue files manually if running Mac OS 9.

TODO / BUGS

  • Specifying other attributes (transactions, etc.)

  • Add more coercions etc. to Mac::AppleEvents::Simple (feedback wanted on this, let me know what I missed)

  • Add comparison operators from glues ?

  • "tell" objects to do events

  • New AETE flags in Mac OS 8.5, Mac OS 9? Anything else new? Anything missing in backward compatibility to 7.5?

  • System of versioning (for glues and target apps) for distribution of modified glues

  • MacPerl (I think) needs a new idle function for waiting for replies

  • MacPerl hangs if it waits for a reply after sending an event to itself

  • Handlers (on foo ...) ?

  • Callbacks (some support exists, Cameron Ashby <cameron@evolution.com>, see Mac::AppleEvents::Simple) ?

  • Add dynamic fetching of glues?

HISTORY

v1.01, Tuesday, January 15, 2002

Clean up a bit for 5.6.

Add ADDRESS method.

Add checking for enumerators and classes.

Make error handler work as hashref parameter list.

Change license to be that of Perl.

v1.00, Tuesday, September 12, 2000

Added error handling via ERRORS parameter / method.

General cleanup, additional examples.

v0.58, Tuesday, November 16, 1999

Change all of the classes to have Mac:: at the beginning of them (except for ones that originate elsewhere, like AEDesc, et al).

Added Mac::AEParamType and param_type.

If a parameter expects an AE object specifier record, and is not passed one, then it guesses the type and sets it to either typeChar or typeInteger.

Made the conversion of keys into English names recursive with lists, in addition to records (i.e., lists can contain multiple records).

v0.57, Tuesday, November 2, 1999

Added conversion of keys in returned records back into the "English" names.

Records containing class parameter are coerced into descriptors of that class (i.e., {name => 'foo', class => 'disk'}).

Added support for events over TCP/IP (Mac OS 9 required).

Note: if Keychain Access is used in Mac OS 9, the login method may no longer be required for accessing of remote machines.

Fixed bug in can method; also changed how can calls AUTOLOAD.

Added code for experimental callback stuff, undocumented, subject to change, and probably does not even work.

Changed _get_name to _get_id, created new _get_name.

Updated dialect creation code for Mac OS 9 (aeut is now stored in the AppleScript extension instead of a dialect file, but for Mac::Glue is still stored in the dialects folder. Instead of being called English, it will likely be called AppleScript. You should delete (or archive) old dialect glues manually.

v0.56, Friday, September 10, 1999

If plural class is used (i.e., files for file), and the following value is not an AE* object, then it will become "every class". (Jeff Lowrey)

Added more documentation about using AEObjDesc objects. (Jeff Lowrey)

v0.55, Thursday, September 2, 1999

Added extra arguments to new to accept alternate targets. PPC ports, PSNs, and paths are explicitly accepted now. (Paths are first launched, then the PSN is found ... aliases won't work properly as paths.)

Added login class method to tell MacPerl to try logging in with specified username and password. Requires Login As OSAX from the GTQ Scripting Library.

v0.51, Wednesday, September 1, 1999

Changed ordering of search in _find_event.

Fixed doc problems in Mac::AETE::Format::Glue: inheritance classes are named, and optional parameters are properly denoted.

v0.50, 12 July 1999

Added g* constants in addition to glue* constants. Use whichever you like, but I will use g* for everything. If you don't want the g* constants, because they conflict with something, use the :long and :longall import tags instead of :glue and :all.

Gone to beta! Woo!

v0.31, 22 June 1999

Fixed bug that only found class names instead of class and property names in creation of object specifier records.

Fixed bug which changed directories on initialization, and didn't change it back.

Allow case-insensitive parameter names.

v0.30, 16 June 1999

Changed function names: glueInsertion is now location, glueRange is now range.

Added whose function.

Added can method which correctly finds available events.

Made special parameters, formerly with leading underscore and lowercase, to all uppercase with no underscore (i.e., _retobj is now RETOBJ).

Added of and in as synonyms for property in obj method calls.

Put AEObjDesc back in! Will use in the future, maybe, to use objects as targets for events.

Return all descriptors from obj and prop, and all objects returned from events, as AEObjDesc objects.

Added glueTrue and glueFalse constants.

Tried again to suppress warnings during initial scripting additions and dialect creation.

Tons of internal cleaning up.

v0.26, 07 June 1999

Made choice of serializer for glue more intelligent: FreezeThaw automatically picked for CFM68K, Storable for PPC.

Updated Mac::AppleEvents and Mac::Memory, fixed more bugs and added constants. Fixed bug in AutoSplit.

Added glueInsertion, glueRange, and glueNull.

Completely removed AEObjDesc package, which existed to support destruction of descriptors. Use global hash now to keep track of descriptors to destroy (Mac::AppleEvents::Simple). So all descriptors returned from obj and prop and others are AEDesc objects.

Changed ordering of items in creating object specifiers in _do_obj to match AppleScript, so comparing to Capture AE output would be easier.

Put %AE_PUT back in Mac::Glue and left %AE_GET in Mac::AppleEvents::Simple.

Switched DOBJ, {PARAM1 => DATA1} to DOBJ, PARAM1 => DATA1 in event calls.

Always default to wait for reply and no timeout if unspecified by user.

Return useful errors in $^E.

Accept and return nested arrays/lists and hashes/records.

Call events and pass classes / properties case-insensitively.

Other miscellaneous changes. Some cleaning up.

v0.25, 30 May 1999

Add serializer option.

Updates to Mac::Memory and Mac::AppleEvents and Mac::AppleEvents::Simple.

Added constants for absolute and relative positions.

Added enum.

Put o and p back as obj and prop.

Other miscellaneous changes. Lots of cleaning up.

v0.20, 22 May 1999

Complete rewrite. Too many changes to bother mentioning, because I am lazy.

v0.09, 13 October 1998

Added ability to use properties. These are called with the p method:

        $obj->get($obj->p('label_index', item=>'HD'));

which is equivalent to:

        $obj->get($obj->o(property=>'label_index', item=>'HD'));
v0.08, 10 October 1998

Unreleased.

Significant cleanup of module, in large part unfinished changes from last version.

No longer doing error checking for whether lists are allowed or objects are allowed, because these are sometimes wrong or undetectable. Also, will not raise exception on a missing required parameter, but will warn if -w is on.

obj_form is exported from the glue modules, and all of the functions and constant from Mac::AppleEvents can be imported from a glue module with the :all tag:

        use Mac::Glue::SomeApp qw(:all);
v0.07, 30 September 1998

More documentation and bugfixes. Having serious problems with AEObjDesc::DESTROY.

v0.06, 29 September 1998

Whole bunches of changes. Note that glues made under 0.05 no longer work.

AUTHOR

Chris Nandor <pudge@pobox.com>, http://pudge.net/

Copyright (c) 1998-2002 Chris Nandor. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

THANKS

Matthias Neeracher <neeracher@mac.com>, David Schooley <dcschooley@mediaone.net>, Graham Barr <gbarr@pobox.com>, John W Baxter <jwblist@olympus.net>, Marion Delgado <dhp@efn.org>, Eric Dobbs <dobbs@visionlink.org>, Josh Gemmell <joshg@ola.bc.ca>, Alex Harper <harper@misanthrope.net>, Nathaniel Irons <irons@espresso.hampshire.edu>, Dave Johnson <dave_johnson@ieee.org>, Bart Lateur <bart.mediamind@ping.be>, Jefferson R. Lowrey <lowrey@mailbag.com>, Mat Marcus <mmarcus@adobe.com>, Larry Moore <ljmoore@freespace.net>, Ricardo Muggli <rtmuggli@carlsoncraft.com>, Vincent Nonnenmacher <dpi@pobox.oleane.com>, Henry Penninkilampi <htp@metropolis.net.au>, Peter Prymmer <pvhp@best.com>, Ramesh R. <sram0mp@radon.comm.mot.com>, Axel Rose <rose@sj.com>, Stephan Somogyi <somogyi@gyroscope.net>, Kevin Walker <kwalker@xmission.com>, Matthew Wickline <mattheww@wickline.org>.

(If I left your name out, please remind me.)

SEE ALSO

Mac::AppleEvents, Mac::AppleEvents::Simple, macperlcat, Inside Macintosh: Interapplication Communication.

        http://sf.net/projects/mac-glue/

VERSION

v1.01, Tuesday, January 15, 2002