Perl calling AppleScript

2004-01-15 Thread Doug McNutt
I just saw this on the AppleScript mailing list.
John is probably not a member of this list but I'll bet someone here can help off list.

Isn't there a module available?

To: [EMAIL PROTECTED]
From: John DeYoung [EMAIL PROTECTED]

 Begin copy 

Apologies for being a little off-topic...

I've inherited a Perl script with a few routines invoking AS commands which, being 
written a couple of years ago, expects to make the calls through MacPerl.  Needless to 
say, it breaks under OS X, but the client still wants to use it.

As you'll soon figure out, my Perl is pretty much limited to spelling its name 
correctly, so I may be up against something trivial, but does anyone know how I can 
rewrite the MacPerl calls to run straight through the included Perl under OS X?  The 
operative sections all look like this:

{

MacPerl::DoAppleScript(END_SCRIPT);

tell application $myApp
[...]
end tell

END_SCRIPT
}

Thanks in advance,
-John DeYoung
 End copy 

-- 
--  There are 10 kinds of people:  those who understand binary, and those who don't 
--


Re: Perl calling AppleScript

2004-01-15 Thread Chris Nandor
In article [EMAIL PROTECTED],
 [EMAIL PROTECTED] (Doug McNutt) wrote:

 I just saw this on the AppleScript mailing list.
 John is probably not a member of this list but I'll bet someone here can help 
 off list.
 
 Isn't there a module available?

Yep.  A few.


 I've inherited a Perl script with a few routines invoking AS commands which, 
 being written a couple of years ago, expects to make the calls through 
 MacPerl.  Needless to say, it breaks under OS X, but the client still wants 
 to use it.
 
 As you'll soon figure out, my Perl is pretty much limited to spelling its 
 name correctly, so I may be up against something trivial, but does anyone 
 know how I can rewrite the MacPerl calls to run straight through the included 
 Perl under OS X?  The operative sections all look like this:
 
 {
 
 MacPerl::DoAppleScript(END_SCRIPT);
 
   tell application $myApp
   [...]
   end tell
 
 END_SCRIPT
 }
 
 Thanks in advance,
 -John DeYoung

The module you want is MacPerl.  Yes, really.  :-)  It is included as part 
of the Mac-Carbon distribution for Mac OS X, which includes the MacPerl.pm 
module, and others that were formerly for Mac OS only.

Other options include Mac::AppleScript with its RunAppleScript() function 
(that module was written before MacPerl.pm was ported to Mac OS X); and 
Mac::OSA::Simple, which is a more generic interface to OSA languages, and 
had an applescript() function.  It also provides a way to compile an 
AppleScript for executing multiple times, or saving to disk, and can load 
compiled scripts from disk to execute.

All three functions -- DoAppleScript(), RunAppleScript(), and applescript() 
-- function in essentially the same way.  DoAppleScript() allows the most 
compatibility with MacPerl scripts.  applescript() doesn't have significant 
advantages in its basic form, as it requires Mac-Carbon anyway, but offers 
some extra control.

RunAppleScript()'s only real advantage, that I know of, is that it takes 
less to install, as Mac-Carbon is a fairly large and powerful distribution, 
and Mac-AppleScript just does this one thing.

There is also calling osascript directly using ``, but that is more error 
prone and has no benefits of its own, apart from not needing to install 
additional modules.  I personally don't consider that a significant benefit.

If you are concerned about performance, all are suitable for most tasks, 
except for `osascript`.  I ran some Jaguar benchmarks once
(http://www.nntp.perl.org/group/perl.macperl/2748), and here's the result
under Panther:

   #!/usr/bin/perl
   use strict;
   use warnings;

   use Benchmark qw(timethese cmpthese);
   use Mac::AppleScript 'RunAppleScript';
   use MacPerl 'DoAppleScript';
   use Mac::OSA::Simple 'applescript';

   my $script = 'tell application Finder to get name of startup disk';
   my %tests = (
 applescpt  = sub { applescript($script) },
 doscript   = sub { DoAppleScript($script)   },
 runscript  = sub { RunAppleScript($script)  },
 osascript  = sub { `osascript -ss -e '$script'` }
   );

   my $results = timethese(500, \%tests);
   cmpthese($results);

   =

   Benchmark: timing 500 iterations of applescpt, doscript, osascript, 
runscript...
applescpt:  4 wallclock secs ( 1.70 usr +  0.29 sys =  1.99 CPU) @ 
251.26/s (n=500)
 doscript:  2 wallclock secs ( 1.11 usr +  0.18 sys =  1.29 CPU) @ 
387.60/s (n=500)
osascript: 240 wallclock secs ( 0.17 usr  2.34 sys + 108.88 cusr 48.57 
csys = 159.96 CPU) @ 199.20/s (n=500)
runscript: 21 wallclock secs ( 6.22 usr +  6.91 sys = 13.13 CPU) @ 
38.08/s (n=500)
   Rate runscript osascript applescpt  doscript
   runscript 38.1/s--  -81%  -85%  -90%
   osascript  199/s  423%--  -21%  -49%
   applescpt  251/s  560%   26%--  -35%
   doscript   388/s  918%   95%   54%--

   =

As noted previously: I don't know why RunAppleScript is a bit slower, and 
osascript is slower because it needs to call out to the shell.  The 
comparison table is deceptive for osascript because it only shows usr+sys, 
not the rest.


Summary: I recommend installing Mac-Carbon, adding use MacPerl; to the 
script, and using it as-is.  If you don't want to install all of Mac-Carbon, 
Mac-AppleScript is your best bet.  Stay away from osascript.

Cheers,

-- 
Chris Nandor  [EMAIL PROTECTED]http://pudge.net/
Open Source Development Network[EMAIL PROTECTED] http://osdn.com/