[Date Prev][Date Next][Thread Prev][Thread Next] [Search] [Date Index] [Thread Index]

[MacPerl] playing with Applescript



I've been playing with Applescript, and I stumbled over a very interesting
possibility, which I haven't seen documented anywhere. So I'll share it with
you all here.

This is it: it is possible to use subroutines in *other* Applescripts stored
as applications.

Try this as an example:

    on greeting(name)
        display dialog "Hello, world!" & return & "Greetings from " & name & "."
    end

Store this as an application called "AS server", never show startup screen,
and stay open. The latter isn't really necessary, but it has the most
interesting possibilities.

Now, close it in the script editor, and build a new script, like:

    tell application "AS server"
        greeting("Bart")
    end tell


Run it, you'll get the dialog box, including the name you entered. Look at
the result window, and you'll see "{button returned:"OK"}", the result from
display dialog. So there is no real difference between defining a subroutine
within a script, and storing it in a seperate applet.


>From MacPerl, this gives you the possibility to build large scripts, and run
them without huge compilation times, every time.


I have build a library this way to control QuarXpress (the DTP program),
allowing me to build quite complex pages. The "server" as I call it, shields
me from the complicated details of the actual apple-event messages sent to
Quark.


The good news: it runs very well with an application memory partition of
only 200k.

Other interesting features: An application script retains it's property
values between runs, without having to "store script" at the end. If it
stays open, it will also retain normal global variable values, between
compilation runs of your "client program".

It is a far more interesting alternative to

    &MacPerl::DoAppleScript(<<EOS);
    set lib to load script "(scriptpath)"
    tell lib
        greeting("Bart")
    end tell
    EOS

because the script file doesn't have to be loaded every time, because it
stays in memory.



Disadvantages (from within MacPerl): Compilation times are still large. Take
this example:

    &MacPerl::DoAppleScript(<<EOS);
    tell application "QXP server"
        init()
        textbox(15,25,100,40)
        setFrame(0.8,"Black",100)
        setBackground("Yellow",20)    
    end tell
    EOS

This brings QXP to the foreground, puts a text box on the current page,
makes a frame around it of 0.8 point (1 point is 1/72 inch, about 0.28 mm,
and quite a natural feeling way of setting line widths), 100% black, and
makes it's background yellow with a shade of 25% (light yellow). 

All this is done in calling 3 (plus 1) subroutines in "QXP server".

If you run this script in Script Editor, it takes 11 seconds to execute. Of
those, only 7 to actually build the text box.


Do the same in MacPerl, and it will take 26 seconds. So: it takes over twice
as long to compile, than to execute! And let's be honest, taking over 15
seconds to compile only a few lines is nothing else than a disgrace.


And for those people interested in extending MacPerl's capabilities in
dealing with Apple-events, the tricky part: a script saved as an application
does *not* have an aete or aeut resource. So, in order to be able to control
server applets like these, you need more than just checking the aete resource.


I'm not familiar with the technicalities of the Mac. (I do have a copy of
"Inside Macintosch", "Interapplication Communication", lying around. Finding
anything useful in it is quite impossible.)

But my guess is that the command is actually sent as a piece of text,
because the command name doesn't even have to exist. You'll only get an
error message *after* the message is sent.

Bart Lateur,
Gent (Belgium)

--- Embracing the KIS principle: Keep It Simple