Tuesday, August 21, 2007

Using Perl's Mac::Glue

Are you like me? Did you get a Mac and are in awe of the integration of everything? It was one of the reasons I got a Mac, yet I didn't look into the details of how everything was integrated. How do applications "talk" to one another?

No, it was not Appletalk (yet that seems fitting word-wise). It's Applescript.

I may be a Mac newbie, yet I don't like "programming" Applescript at all. It should be natural, yet it isn't. It's actually very frustrating, yet that's just part of learning it.

To quote devintosh.com FAQ (freenode IRC network #macdev channel):
I have a problem with my AppleScript, can you help?
Probably not. AppleScript is a crappy language that makes it hard to do almost anything. If your AppleScript code is more than a few lines then you're already going beyond what it's good at. Learn a real language: it's harder to start with and it takes time to learn, but in the end you'll be solving more problems and solving them faster

Ok, I got that. Am past it... I still don't like it (thanks to mikeash on #macdev for enlightening me... before I went too far down the wrong rabbit hole).

I want a real programming language to be able to do the same things Applescript does. Isn't there a way?! Yes! There is Mac::Glue, which gives you all the same functionality of Applescript except you can now do it in Perl. Hrm... sounds like a bunch of bologna? Yeah, I agree... till I poked around into learning it. I'd like to share with you what I found.

First, install Mac::Glue. It's in MacPorts (p5-mac-glue) or you can install it via CPAN. Either way doesn't really matter, but in these examples I'll be using the MacPorts version (it's Perl is newer). Be sure to read the README file in the tarball. You will need to create the "glue" for programs you want to work with, ex: "sudo /opt/local/bin/gluemac /Applications/iTunes.app". No big deal, just be sure to do it for programs you plan on working with.

Second, note this isn't a full coverage of all that Mac::Glue does. This just shows how to port over some Applescript and "talk" to other programs via their bindings.

Now, to my favorite part. Some code! [sorry, it's not that impressive -ed.]

In the first example, lets port over something easy like "/Library/Scripts/Basics/AppleScript Help.scpt". It opens up 'Help Viewer.app', activates it, and then searches looking for 'AppleScript'.

Here is the AppleScript code:

tell application "Help Viewer"
search looking for "AppleScript"
end tell

Here is the Perl code:

# Glue requirement:
# * sudo /opt/local/bin/gluemac "/System/Library/CoreServices/Help Viewer.app"
# Port of:
# * "/Library/Scripts/Basics/AppleScript Help.scpt"
use strict;
use warnings;

use Mac::Glue;

my $glue = new Mac::Glue 'Help_Viewer';
$glue->search(looking_for => 'AppleScript');

You may be wondering how I knew what subroutine to call. It's in the glue code pod file. Since I'm using MacPorts in these examples, I did this: "perldoc /opt/local/lib/perl5/vendor_perl/5.8.8/Mac/Glue/glues/Help_Viewer.pod". Be sure to look in that directory for help on how to use the "glue".

How about a simple adding someone to your address book?

# Glue requirement:
# * sudo /opt/local/bin/gluemac "/Applications/Address Book.app"
# Explanation and original code examples from Chris Nandor:
# * http://www.nntp.perl.org/group/perl.macosx/2004/04/msg7285.html
use strict;
use warnings;

use Mac::Glue ':all'; # all for 'location'

my $glue = new Mac::Glue 'Address_Book';

my $me = $glue->make (new => 'person',
with_properties => {
'first_name' => 'Steve',
'last_name' => 'Jobs'
$glue->make (new => 'email', at => location(end => $me->prop('emails')),
with_properties => {
'value' => 'fakestevejobs@gmail.com',
'label' => 'home'

I'm still a Mac::Glue and AppleScript newbie. There is much to learn, yet all the power that is desired is available at your finger tips. I hope this was communicated enough to educate you that it does exist and you can use it in place of AppleScript for use in real programs.

Much thanks to Chris Nandor and everyone else that may have been involved in Mac::Glue.

I still have much to learn, yet at least we both know that we can do what we need in Perl... at least in this respect. In any place you can use AppleScript, try using Mac::Glue instead. I recommend getting the FastScripts utility if you can, it's like the regular AppleScripts menu, yet much more flexible as it can run any kind of program and have custom keybindings (very handy).

To be fair, before I get complaints in my inbox, the ability to do the same thing exists for Ruby, Objective-C and Python available at http://appscript.sourceforge.net/. I played with it in Python and Ruby and it seems to work very well. So, give it a try if you're not a Perl coder.

Do you have any cool Mac::Glue examples? If so, post them and happy hacking!


Skeeve said...

As far as I know, Mac::Glue comes standard with your OS X

has said...

Mac::Glue is included in OS X 10.4's standard Perl installation, but last time I looked it was an old version that only works on PPC so if you're on an Intel Mac you'll need to update it yourself.

Christopher Humphries said...

Hrm, I don't remember seeing it when I looked before, yet great to know :)
Just one less thing to worry about, thanks! (I have an Intel Mac, a sexy black Macbook)

Also using MacPorts due to current version of Perl (5.8.8 versus 5.8.6) and staying current with my other installed modules.