Team LiB   Previous Section   Next Section

8.1 Subroutines with Positional Parameters

The AppleScript subroutines with positional parameters are simple to design and use, as long as you meet certain guidelines. The keywords on or to are required in the subroutine definition, followed by the name of the subroutine, and any parameters separated by commas and contained in parentheses. You have to use empty parentheses following the subroutine name if the subroutine will not take any parameters. The subroutine's name must comply with AppleScript's rules for identifiers. In AppleScript, the names that you create for variables and subroutines have to begin with a letter or underscore ( _ ) character, but subsequent characters can include letters, numbers, and underscores. Unless you begin and end the subroutine name with a vertical bar (|), you cannot include AppleScript's reserved words and operators such as *, &, ^, or +, or special characters such as $, @, or #.

The end keyword is required to signal the end of the subroutine definition. You can follow end with the subroutine name for the sake of readability:

On Squared(n1)...end Squared

This is not required, however; the compiler, Script Editor, does it for you. You can declare and give values to variables in AppleScript subroutines, and use the various flow-control statements such as:

if...then...end if

and:

repeat...end repeat

However, you cannot define another subroutine inside of a subroutine definition.

To call a subroutine, use the subroutine name followed by its parameters inside of parentheses:

Squared(7)

With subroutines that take positional parameters, you have to code the arguments in the same order as they appear in the subroutine definition. You have to include all of the specified arguments—the arguments in AppleScript subroutines are not optional (nor can they be declared as optional). Use empty parentheses with subroutine calls if the routine does not take any arguments. You can also use expressions, other variables, and other subroutine calls to give the parameters values, as in:

Squared((7*2))

or:

Squared(DividedBy(8))

If you use a subroutine to give a parameter a value, that subroutine must return a value. Example 8-2 is a complete subroutine definition that takes one number as its parameter and returns that number squared. The first set of comments, beneath on squared(num), describe how to call the method, as well as its parameters and return value.

Example 8-2. AppleScript Subroutine Definition
on squared(num)

   (* 

   call method as: Squared(number)

   parameters: an integer or real type

   returns: the parameter squared, or zero if the param is not a valid

   *)

   if class of num is in {real,integer}  AND num  0 then

      return num ^ 2

   else

      return 0

   end if

end squared

Set big_number to Squared(2345)

When you are creating subroutines with positional parameters, you can design them to return a value to the part of the script that called the subroutine in the first place. You can use the return keyword, with or without a literal value or expression:

return 0 -- or just 'return' alone, without a specified value

Using return with a Boolean value (e.g., return true) allows you to signal the successful or failed execution of the subroutine. Using return without a value stops execution of the subroutine and returns the flow of execution to the part of the script that called the subroutine. If you do not use the return statement in a subroutine, the routine returns the value of the last expression that was evaluated in the subroutine (if the last expression returns a value). If the last expression in the subroutine does not return a value, and if the subroutine does not use the return statement followed by an expression or value, then the routine does not return a value. See Example 8-2 and Chapter 6, or Chapter 7, for other examples and discussions of the return statement.

By default, any variables declared inside the subroutine are local to the routine. This means that the scope of the variables is restricted to the routine; if you try to access the variable outside of the subroutine, the script will fail to compile. You can explicitly declare a variable as local by using the local keyword, as with the variable dstring in Example 8-3. This is good practice for using local variables, as it makes the subroutine definition easier to understand.

A variable can also be declared as global inside of the routine. This is accomplished by using the keyword global followed by the name of the variable:

global myvar

This means that the variable is visible outside of the subroutine. Chapter 6 discusses local and global variable scope.

Example 8-3 takes a date object as an argument and returns a "month day year" string such as "August 3 1999." If the argument is not a date object such as:

if class of theDate is not date

then the subroutine returns the string "invalid argument." You could return 0 or raise an error dialog box as an alternative. The local dstring line declares a dstring variable whose scope is restricted to the ReturnDate subroutine; it is not "visible" outside of the routine. The local dstring declaration is not strictly necessary since first declaring the dstring variable inside of a subroutine definition automatically makes it a local variable, unless the global keyword is used ("global dstring"). But using the local keyword in this manner makes the subroutine definition more readable.

Example 8-3. A User-Defined date Subroutine
on ReturnDate(theDate)

   if class of theDate is not date then return "invalid argument"

   local dstring

   set dstring to (theDate as string)

  (*

   call method as: ReturnDate(current date)

   parameters: theDate is a date (not a string) such as date "Tuesday, 

   February 6, 2001 12:00:00 PM" returns: A string that looks like 

   "February 6 2001"

   *)

   set mon to the second word of dstring

   set dy to the third word of dstring

      set yr to the fourth word of dstring

return mon & " " & dy & " " & yr

end ReturnDate

If you call one of your own subroutines inside of a tell statement, such as:

tell app "Finder"...end tell

AppleScript responds to the subroutine call as an application command (in this case, of the Finder) unless you use the my or of me keywords. Example 8-4 calls the script's squared subroutine (instead of looking in the Finder's dictionary for a squared command), because the script uses the my keyword in calling the routine. This is just a demonstration script; you would only use a tell statement if the script were also sending the Finder some commands.

Example 8-4. Using the my or of me Keywords
tell application "Finder"

   my squared(7)

end tell

on squared(num)

   if class of num is in {real, integer} and num  0 then

      return num ^ 2

   else

      return 0

   end if

end squared
    Team LiB   Previous Section   Next Section