DekGenius.com
Team LiB   Previous Section   Next Section

8.2 Subroutines with Labeled Parameters

These subroutine types are a slightly different animal than the subroutines with positional parameters, but they have some of the same rules. The keywords on or to are required in the labeled-subroutine definition, followed by the name of the subroutine, and optionally a nonlabeled parameter called a direct parameter. If the subroutine has a direct parameter (it does not have to), then the subroutine name has to be followed by the keyword of or in:

On Square of intOne...

Subroutines with labeled parameters are unwieldy to design compared with subroutines with positional parameters, but they make more subroutine calls resembling human language possible. The two different types of AppleScript subroutine designs are also a matter of personal taste, I suppose. Example 8-5 shows a labeled subroutine definition.

Example 8-5. Labeled Subroutine Definition
on Square of intOne above intLimit given Intclass:theClass
   if (intOne > intLimit) and (theClass is integer) then
      return intOne ^ 2
   else
      return 0
   end if
end Square
Square of myint above 0 given Intclass:(class of myint)

Example 8-6 redesigns the preceding subroutine using positional parameters instead.

Example 8-6. A Redesigned Subroutine Using Positional Parameters
on Square(intOne,intLimit,theClass)
   if (intLimit > 0) and (theClass is integer) then
      return intOne ^ 2
   else
      return 0
   end if
end Square

The rules on naming the subroutine (using local and global variables) and ending the subroutine definition are the same as those that apply to naming subroutines with positional parameters (see the previous section). In the following example, the direct parameter is followed by the first labeled argument, above intLimit:

on Square of intOne above intLimit given Intclass:theClass

Along with above, you can use the following AppleScript reserved words: about, against, apart from, around, aside from, at, below, beneath, beside, between, by, for, from, instead of, into, on, onto, out of, over, since, through, thru, and under. These words have no meaning in the context of calling labeled routines except to make the subroutine call more readable. Instead of writing:

on Square intOne above intLimit given Intclass:theClass

you could substitute:

on Square of intOne apart from intLimit given Intclass:theClass

and the subroutine, as long as its other elements were legal, would run the same.

If the subroutine with labeled parameters has a direct parameter (they do not have to), then the definition must also include either one of the aforementioned labels (e.g., thru), a given labeled argument, or both of these parameter types. The given label takes a variable:value pair as a parameter, which can be used to find out whether a value is true or false:

given theBool:boolVal

In Example 8-5, given Intclass:theClass is used. You then give Intclass a value when calling the routine:

Square myint above 0 given Intclass:integer

The body of the subroutine evaluates the value of Intclass.

To call one of these subroutines, you have to include the direct parameter if one has been defined for the routine. If the routine defines any of the parameters that use AppleScript's reserved words (such as thru or above), they come next (if there are more than one, then these parameters may be called in any order). Any given parameters must come after the other labeled arguments. You have to include all the arguments defined by the subroutine—the arguments defined in AppleScript subroutines are not optional when the routine is called. Unlike the routines with positional arguments, when you call a subroutine with labeled parameters, you do not surround the arguments with parentheses. But you have to include the labels and parameter values (or any variables containing the values) in the subroutine call.

idle handler

Syntax

on idle
   return 600 -- idle is called every 10 minutes
end idle

Description

AppleScripts can be saved to stay open after they have been executed, instead of completing their tasks and quitting. Chapter 2, discusses the nuances of saving AppleScripts. These scripts may define an idle handler, essentially a subroutine that AppleScript calls by default every 30 seconds when the script has been launched and is open. You can change this time interval by returning a positive number (a real is legal but an integer makes more sense) from the idle handler. The syntax example returns 600, or the equivalent of 10 minutes, which will be the new time interval for AppleScript's execution of this idle handler. If the handler returns any value other than a positive number then the time interval is kept at the 30-second default. The idle handler should have some purpose other than altering the interval by which it is run, as in the code in the following Examples section. Another example that typifies an idle handler's role is to lurk in the background monitoring the usage of a folder that network users have access to. When the folder's content changes, the handler can note that in a log entry, for instance.

Examples

The following idle handler example makes the Netscape browser the front window every 10 minutes and reloads or forces a fresh reload (that is where the flags 3 labeled parameter for Netscape's OpenURL command comes in) of the URL http://my.yahoo.com. You can see how an idle handler would come in handy if you wanted to do more complex web processing, such as periodically seizing data from the Web and storing it in your desktop or network database.

An intriguing use of stay-open scripts is to use them as live subroutine libraries that are stored in memory and can be called from other scripts. Take a bunch of useful subroutines that other scripts could use, and save them together in a stay-open applet. Execute the applet. Then call the subroutines using a tell statement that targets the name of the applet. These subroutines that are stored in open applets can even return values to the calling script, as in the following example. You do not have to define an idle handler inside a stay-open script or library, unless this stay-open applet has to do some processing itself.

on idle
   tell application "Netscape Communicator™"
      activate
      (* the 'flags 3' param forces a reload of the document from the server *)
      OpenURL "http://my.yahoo.com" flags 3
   end tell
   return 600 -- call idle every 10 minutes, if Yahoo doesn't mind
end idle
 (* here are two subroutines defined in a stay-open applet called 'RunningLib' 
*)
on timesTwo(num)
   return num * 2
end timesTwo

on divTwo(num)
   return num / 2
end divTwo

(* Here's another applet that calls RunningLib's subroutines and gets values 
from them *)
set mynum to 0
tell application "RunningLib"
   set mynum to divTwo(timesTwo(75))
end tell
mynum -- value is 75.0

To quit a script that has been saved to "stay open" and contains an idle handler, you can choose Quit from the File menu on its menu bar (yes, stay-open scripts have a menu); select the script icon in the Application Switcher and type Command-Q, or send the app a quit command from another script.

open handler

Syntax

on open(list_of_aliases)
   set item1 to the first item of list_of_aliases as string
   display dialog "Here's the path of the first object you dragged over¬ 
   me: " & item1
end open

Description

An open Apple event is sent to any Mac application when you drag file, folder, or disk icons on to its own icon in the Finder. If an icon is not highlighted when you drag the object over it, then the application or other object associated with that icon is not designed to handle these drag-and-drop events. If you drag files and other icons over an AppleScript applet, the applet receives an open command that triggers any open handlers that are defined in that applet. They look like this:

on open(list_of_aliases)...end open

The open handler has one parameter—a list type containing alias objects for all the items that were dragged to the applet. If the user only drops one item on the applet icon, then the open subroutine's parameter will contain a list with one item in it. You can code the open handler to take purposeful actions with files and folders that are dropped on the applet in any way you see fit. Example 2-1 in Chapter 2 shows a script that displays the file type and creator type of any valid object that is dropped on the applet.

If the applet does not have an open handler or has an empty open handler, then the applet does not take any actions when you drop an object on it; it just opens then quits simultaneously.

reopen handler

syntax

on reopen
   display dialog "I am already running; you do not have to double-click
   me!"
end reopen

Description

The reopen handler is designed for the occasions when a user double-clicks a stay-open applet that is already running. This action executes the reopen handler. So anything that you want to happen when the user tries to "reopen" a script that is already running should be defined within the reopen handler. All this example does is display a dialog to users when they double-click a running applet that contains this reopen handler.

quit handler

syntax

on quit
   display dialog "Sure you want to quit?"
   continue quit -- quits the applet
end quit

Description

Scripters can add quit handlers or subroutines to stay-open applets in order to process code statements whenever the applet receives a quit Apple event. The syntax example displays a dialog whenever its applet receives a quit command, and then it quits when the user dismisses the dialog box because the code includes the continue quit statement. If the code did not include this statement then the applet, in response to a quit command, would call its quit handler and stay open.

Make sure to include the continue quit statement in quit handlers, unless you want the applet to stay open until the next computer restart. A quit handler without a continue quit causes the applet to intercept and nullify the user's efforts to quit the app from its File menu. To bypass the quit handler, choose Quit from the applet's menu while holding down the Shift key, or press the Command-Shift-Q key combo while the applet is the active or front application.

The quit handler is only necessary for stay-open applets, because the applets that are not saved as stay-open will process their statements and immediately quit (see Chapter 2 for more on the nuances of saving applets).

run handler

Syntax

on run
 (* do major scripting here *)
end run

Description

Whether you like it or not, most of your scripts contain a run handler implicitly or invisibly. What Apple Computer calls an "implicit run handler" involves all the statements in a script except for property definitions, subroutine definitions, and any script objects (see Chapter 9). This means that all of these statements are enclosed in an invisible on run...end run subroutine block. This implicit run handler is called each time:

  • The applet icon is double-clicked.

  • The user chooses the applet from the Apple menu.

  • The user chooses the applet from the Apple Menu Items folder.

  • The applet is placed in startup disk:System Folder:Startup Items and the computer is restarted.

You can explicitly code the run handler to clarify to readers of your code exactly what happens when the applet receives a run command, as in the next example. If this script did not include the on run...end run statements, then its implicit run handler would still encompass the statements:

add(  )

and:

display dialog "I received a run command " & howmany & " times"

The applet property howmany increments by 1 each time this applet receives a run command:

property howmany : 0
on run
   add(  )
   display dialog "I received a run command " & howmany & " times"
end run

on add(  )
   set howmany to howmany + 1
end add

Sending a run command to an application, as in tell app "Photoshop 5.5" to run, loads the application if it is not already running. Use activate to gain the focus of the application (i.e., highlight the program on the desktop) when it is already running. Sending a run command to an AppleScript causes its implicit or explicit run handler to execute.

    Team LiB   Previous Section   Next Section