Hi all,
Just wanted to note that, in addition to the Google Groups mirror, Apple also maintains an
archive of digests for the AppleScript-Users list. When prompted via the security/login dialogue, just specify username 'archives' and password 'archives' (as mentioned on the dialogue itself, and near the bottom of the
AS-Users info page). Unfortunately, the archive isn't yet searchable, so it's still better to use Google Groups if you need to find threads on a specific topic.
BTW, koolmeme, it is indeed possible to pass any object (including handlers) from one script (or script object) to another, either within the same applet or across several applets. The 'load script' command of the Standard Additions OSAX is useful for this purpose.
E.g., one could set up several script objects to work as "pseudo-classes" encapsulating various properties and handlers, and then load those script objects into a stay-open "server" applet. Other "client" applets could then get or set various properties and handlers in the server applet, via the usual 'tell' statements or 'of' clauses. (The AppleScript Sourcebook web site also has some good tips on
Script Servers and other topics.) Alternatively, one might prefer not to use either script objects or script servers, but rather simply call handlers in one stay-open applet directly from another applet on a peer-to-peer basis.
As you mentioned, Apple's official AppleScript Language Guide does provide some helpful details, especially in Chapter 9 "Script Objects". In addition, although there is no explicit mention of this in the AS Language Reference, it is even possible to "variablise" and pass around a handler from a loaded script object or a stay-open applet (as long as the calling script stores the supplied handler into a property or a
pre-initialised global), and then later call that handler-var just as if it were the actual handler. I use this latter approach myself in some of my library scripts.
For instance, one could create the following stay-open applet named 'Client Applet' to receive a 'Square' handler from another stay-open applet named 'Server Applet' (see next code snippet below this one):-<BLOCKQUOTE><font size="1"face="Geneva, Verdana, Arial">code:</font><HR><pre><font size=1 face=courier>-- A <font color = red>"handler-variable"</font>, to store the handler received from the Server
property thePassedHandler : (missing value)
-- ---------------------------------------------------------------------------------------------------
on run
-- Do nothing other than resetting our internal <font color = red>"handler-var"</font>; our 'Idle' handler will <font color = green>do</font> the real work
set thePassedHandler to (missing value)
<font color = green>return</font>
end run
-- ---------------------------------------------------------------------------------------------------
on idle
-- Wait <font color = green>for</font> the Server to send us its handler
<font color = green>if</font> (thePassedHandler is not (missing value)) then
-- Display the result of calling the supplied handler
activate
display dialog (<font color = red>"Square of <font color = blue>2</font> = "</font> & (thePassedHandler(<font color = blue>2</font>))) ¬
buttons {<font color = red>"OK"</font>} <font color = green>default</font> button <font color = blue>1</font> with icon note
-- Terminate myself
quit
end <font color = green>if</font>
<font color = green>return</font> <font color = blue>5</font> -- We'll wake up every <font color = blue>5</font> secs
end idle
-- ---------------------------------------------------------------------------------------------------
on SetHandler(theHandler)
-- Store the supplied handler into our internal property
set thePassedHandler to theHandler
<font color = green>return</font>
end SetHandler</font>[/code]
Then, another stay-open applet named 'Server Applet' could be set up to explicitly pass its 'Square' handler to the 'Client Applet' as follows:-<BLOCKQUOTE><font size="1"face="Geneva, Verdana, Arial">code:</font><HR><pre><font size=1 face=courier>-- A flag to keep track of whether we've passed our handler to the Client
property bPassedHandler : false
-- ---------------------------------------------------------------------------------------------------
on run
-- Do nothing other than resetting our internal flag; our 'Idle' handler will <font color = green>do</font> the real work
set bPassedHandler to false
<font color = green>return</font>
end run
-- ---------------------------------------------------------------------------------------------------
on idle
-- Check whether we still need to <font color = green>do</font> our duty
<font color = green>if</font> (not bPassedHandler) then
-- Check whether the Client is now running
<font color = green>if</font> (IsClientRunning() of me) then
-- Set up the client applet object
set theClientApp to (application <font color = red>"Client Applet"</font>)
-- Pass the 'Square' handler to the client applet
-- NOTE: We could also say:- 'tell theClientApp to SetHandler(Square of me)'
-- or, 'tell (application <font color = red>"Client Applet"</font>) to SetHandler(Square of me)'
SetHandler(Square of me) of theClientApp
-- Remember that we've done our duty
set bPassedHandler to true
end <font color = green>if</font>
<font color = green>else</font> -- (* Check whether to rest our internal flag, i.e., <font color = green>if</font> the Client has now quit *)
<font color = green>if</font> (not (IsClientRunning() of me)) then
set bPassedHandler to false
end <font color = green>if</font>
end <font color = green>if</font>
<font color = green>return</font> <font color = blue>5</font> -- We'll wake up every <font color = blue>5</font> secs
end idle
-- ---------------------------------------------------------------------------------------------------
on IsClientRunning()
tell application <font color = red>"Finder"</font>
set theClients to (every application process where its name is <font color = red>"Client Applet"</font>)
set bIsClientRunning to (theClients is not {})
end tell
<font color = green>return</font> bIsClientRunning
end IsClientRunning
-- ---------------------------------------------------------------------------------------------------
on Square(x)
-- Return the square of the param
<font color = green>return</font> (x * x)
end Square</font>[/code]
Once the 'Server Applet' is up & running, then any time the 'Client Applet' is subsequently run, after a few seconds the Client would display the result of squaring 2 and quit. This is a very small example [and not any more powerful than simply calling the Server's Square handler directly ;-)], but hopefully it illustrates the concept of passing handlers (or other objects) around.
Regards,
--Paul