DekGenius.com
Team LiB   Previous Section   Next Section

6.1 Variables

Here are two ways that you can create your own variables in AppleScript:

set int to 20 -- one way to set a variable to an integer

copy 20 to int -- another way

A variable is a word or identifier that the scripter creates to store a script value. An example is the int variable in the statement set int to 20. Along with copy, the set reserved word is used to set a variable name to a value, in this case an integer. AppleScript variables can store any value, including booleans, lists, numbers, records, strings, and application-defined classes. AppleScript variables have to begin with a letter or underscore ( _ ) character, but subsequent characters can include numbers and underscores. You cannot include operators and other symbols that AppleScript reserves for different uses (such as *, &, ^, or +) or special characters (such as $, @, or #). An exception to this rule in AppleScript allows the creation of memorable variable names if you use vertical-bar characters (|) to begin and end the identifier:

set |2$var*&^%#| to 2

AppleScript is not a case-sensitive language, so the variables that include the same characters but in varying case are treated as the same identifier. In other words, myname, myName, and MYNAME are all considered the same variable. Variable names can be one to several characters long, depending on your stylistic preferences.

This AppleScript gives several examples of valid and invalid variable names, as well as how to use the set and copy keywords to declare a variable and store a value in it:

set l to {"a", "legal", "var"} as list (* a variable name can be one letter *)

set a_veryLong_but_legal30_variable500_name to "Too long in my opinion"

copy 500 to int (* using the copy keyword instead of set has the same effect on
integers *)

copy "A string" to str -- creating a string variable with copy

set $perl_string to "Can't imitate perl without pipe characters" (* this will 
raise a compiler error *)

set |$perl_string| to "Recreate a perl scalar variable if you use pipe¬ 
characters"

set 2str#in/g to "You can't start a variable with a number or use¬
special  symbols in it" (* another error, unless you enclose the characters in 
pipe symbols *)

In most cases, you do not have to declare a data type (e.g., integer, string) when you set a value to a variable. You will want to set a variable to a real using the code:

set largeNum to 500000000.0

when further processing will increase it in value beyond an integer's storage capacity (see Chapter 3, for a discussion of the real and integer data types). In addition, date variables have to be declared as dates in the manner of set myDate to date "1/1/2000". Sometimes, the code is a lot clearer to its originator and other programmers when you explicitly set variables to the intended class, even if AppleScript does not require explicit typing (except for date strings).

The reserved word copy has a different effect than set when the value is a list, record, or script object. In other words:

copy 500 to int --or copy "A string" to str

has the same result as:

set int to 500 --or set str to "A string"

With lists, records, or script objects, however, copy creates a new copy of the object in the variable:

set list1 to {"the", "first", "list"}
set list2 to list1 -- list2 refers to list1
copy list1 to list3 -- list3 has a whole new copy of list1
set item 2 of list1 to "different"
log (list2) -- changes to list1 also effect list2
log (list3) (* changes to list1 do not affect list3; it's a different copy of 
the first line *)

The first list (list1) is a list of three strings. The list2 variable is set to the same list. But the third declared variable (list3) receives a copy of the first list. Afterwards, a change to the second string of the first list alters the value of the list2 variable, because it is actually pointing to the changed list. The log (list3) code indicates that the third list, whose list copy was not changed by the set item 2 of list1 to "different" statement, still contains the original list value. Again, this behavior is only true for using copy with a list, record, or script object. (Chapter 9, discusses script objects.)

The log command is used to view the values of variables in Script Editor's Event Log. Chapter 2, is devoted to Script Editor.

6.1.1 Variable Scope

Variable scope refers to the loc ation in a script where variable values can be accessed. A variable that can be accessed anywhere in the script is known as global and has to be declared as such in the script:

global aVariable

AppleScript variables are local by default, meaning that if a script contains both script statements and function or subroutine definitions, then the variables that are declared inside of the function(s) are local (i.e., trying to access them outside of a function raises an error) unless declared as global outside the routine. This element is best illustrated by an example:

set aNum to 7
display dialog (do_it(aNum) as string) (* call the do_it function and display 
its result *)
log avar (* avar variable is not visible at this location; this causes an error
*)
 (* subroutine definition *)
on do_it(v)
   set avar to 0 -- avar is local to the subroutine
   set avar to v + 1
   return avar
end do_it

This script sets an integer variable to 7, then displays the results of a function call using the display dialog scripting addition. The do_it function is defined inside the script. It has an avar variable that is initialized to then used to add 1 to the integer argument that is passed to the function. Though the avar variable provides the return value for the do_it function, it is only known inside the function. The third line of this example, which tries to log the avar value in the Script-Editor Event Log window, raises an error because the avar variable's scope is local to the do_it function. The error dialog reads: "The variable avar is not defined."

The next example solves this problem by declaring avar as global (initializing the variable at this script location, as in set avar to 0, would have the same effect). Then the function call sets the variable to 8, and the Event Log has no trouble logging its value because avar is visible at the top-level of the script:

set aNum to 7
global avar
display dialog (do_it(aNum) as string)
log avar -- avar evaluates to 8
on do_it(v)
   set avar to 0
   set avar to v + 1
   return avar
end do_it

Use the reserved word local to give a variable local scope. In another variation of our script, the avar variable inside the function is first declared as local. This means that there are now two different avar variables, one at the top level of the script and another local avar version that is restricted to the function (outside of an illustrative example like this, you usually wouldn't give two different variables the same name):

set aNum to 7
global avar
set avar to 0 -- global avar is initialized to 0
display dialog (do_it(aNum) as string) -- return value is from local avar
log avar -- global avar still is 0
on do_it(v)
   local avar
   set avar to v + 1
   return avar (* returns the integer 8 but doesn't affect global avar
end do_it *)

6.1.2 Properties

A property is a variable that retains its value after a script has run. Even after you have quit and launched a script again, the script retains its property value. A property has global scope throughout a script. You have to define a property with the property keyword (prop for short), followed by a space, a variable name, a colon character (:), and its initial value:

prop runval : 0

The colon can be preceded and followed by a space, which improves code readability. The following AppleScript creates a howmany property, then increments it by one and displays its value each time the script is run:

property howmany : 0
set howmany to howmany + 1
display dialog (howmany as string)

howmany starts out as 0, then keeps a count of how many times the script has been run. It will not be reinitialized to unless the script is recompiled (optionally altered then saved again). You can set a property to any value type, including booleans, lists, records, and strings. It is good form to declare all properties at the top level of a script, since they are global variables that persist from script execution to execution. You cannot declare a property inside of a handler, as the following example shows. The script successfully displays the value of the aPi property (which is the value of the pi predefined variable, a real number), even though the property is declared beneath the display dialog command. It is better practice to declare all properties at the top of a script:

property aList : {"a", "list"}
property aString : "A string"
property aRecord : {name:"A record", type:"record class"}
display dialog (aPi as string)
property aPi : pi
on init(  )
   property initvar : "I'm inside" (* raises an error and prevents 
   script from compiling *)
end init

You can also declare a parent object for the script by using the syntax property parent : scriptObject or Application. In place of the scriptObjector Application placeholder you include a script object or application. The script with the parent property then inherits the properties, elements, and commands of the parent object. See "current application" in the section Section 6.2 in this chapter and Chapter 9for more information on inheritance in AppleScript.

In sum, you can declare a variable as global at the script's top level if you want to use it throughout the script. The next AppleScript declares a global called initv and then uses it in both the script's run handler and in a user-defined subroutine called init. (Chapter 8, describes the runhandler.) The initv variable is visible inside both subroutines. The as string portion of the (init( ) as string) fragment is not strictly necessary, but otherwise included to make it clear that an integer return value is coerced to a string before it is included in the display dialog text:

global initv
on run
   set initv to 0
   display dialog "Function return value is: " & (init(  ) as string) &¬
   return & "Value of initv is: " & initv
end run
on init(  )
   set initv to initv + 1
end init
    Team LiB   Previous Section   Next Section