Roll Your Own 2: Variables and Data

Originally published in June, 2002.

Variables and Data

Welcome back to Roll Your Own as we continue our journey into the magical world of Macintosh programming. Last month we covered the basics of what programming is and even dove right in and wrote a small program in AppleScript. In this edition of the column, we’re going to delve into one of the most useful programming tools: variables. And since variables store data, we’re also going to talk about data types.

But before we get into that deep subject, let’s get familiar with our programming environment a bit more. As I mentioned in our last column, we’re going to use AppleScript as our programming language of choice. That being the case, there are a number of options as to how we can enter the code for our programs.

No matter which programming environment you use (and if you begin to really get into programming, you’ll come into contact with many programming environments) you’ll want to be as familiar as possible with its capabilities. A programming environment is different from a programming language. The programming environment is where you actually build your programs. It lets you type the code for your program, compile it into machine code, and run it. Some programming environments are phenomenally complex, such as Metrowerks CodeWarrior and Apple’s Project Builder (now Xcode). Others, such as Script Editor, are so simple as to eventually be frustrating.

On every Macintosh computer, in addition to the AppleScript extension, is a small program called Script Editor. This is a very basic text editor that can compile, save, and run AppleScripts, and although it’s rather limited in its features for the programmer, since it’s free, we’re going to assume that this is what you’re using. If you’re interested in editors with more features and power, other possibilities are Scripter, Script Debugger and Apple’s Project Builder on Mac OS X. If you’re just beginning, I wouldn’t yet recommend Project Builder, but Scripter (no longer published) and Script Debugger are both great environments, and when you have more experience with AppleScript, I would definitely recommend taking a closer look at them.

roll-01

The Script Editor Icon

By the way, unless I’m addressing a topic specific to Mac OS 9, the screen shots will all be from OS X, but you should see very similar windows and dialogs in OS 9. If you haven’t yet moved to Mac OS X and you have the hardware to support it, I can’t recommend it highly enough. Yes, my PowerBook G3 is slower since I’ve been running X, but for the last six months it froze exactly twice, both times with Virtual PC 5, and since Connectix released an update to that software and I installed it, I haven’t seen a freeze on it at all. Apple has come through with rock-solid stability on this one, and I believe I’ve more than gained in productivity by avoiding reboots what I’ve lost in OS speed. Another feature in favor of OS X is AppleScript Studio, which we’ll get into once we start talking about the interface of software.

If you’re running any classic version of the Mac OS, you’ll find Script Editor (unless you’ve moved it) at “Hard Disk:Apple Extras:AppleScript:”. On Mac OS X you’ll find it at “/Applications/AppleScript/”. When you launch it, you’ll be presented with a window with some special buttons. The top left has a disclosure triangle with the word “Description” next to it. You can either show or hide the description by using this triangle. The description is for your own purposes and can hold any text you like. I tend to place descriptions of the program within the code of the program by using comments, so I usually keep this hidden.

roll-02

The Script Editor’s Main Window

Below the description are four buttons. We’re not going to worry too much about the first button, “Record,” because we’re studying programming here, not scriptable applications. But suffice it to say that some scriptable applications allow you to record actions and translate them into script commands, which can give you insight into how the program’s commands work with AppleScript.

The second button, “Stop,” allows you to halt the execution of a running program, allowing you to exit it without the program having to finish. This can be useful when there’s a bug in your program and you want to stop before it goes any further. As in many programs, Command-period has the same effect.

Next is the “Run” button. When you click this button, Script Editor compiles your program, if you’ve made any changes since the last compile, and attempts to execute your code. Its keyboard equivalent is Command-R.

To the far right of the window is the “Check Syntax” button. Like the “Run” button, this will compile your code if there have been any changes to it since the last compile. If there haven’t been changes, the button is disabled. You can also check the syntax by hitting the “Enter” key (not “Return”).

Script Editor shows your code in different colors depending on what kind of word the code is. The default on Mac OS X is to display uncompiled text in orange Monaco, operators in black Geneva, AppleScript keywords in bold red Geneva, other keywords in blue Geneva, comments in grey italic Geneva, raw values in black Geneva, variables and subroutines in green Geneva, and references in purple Geneva. In Mac OS 9, almost everything appears in black Geneva by default, but AppleScript keywords are in bold and comments are in italics, while uncompiled text is in Monaco. You can alter these defaults by selecting AppleScript Formatting from the Edit menu.

roll-03

The AppleScript Formatting Dialog

Saving a script in Script Editor works just like other Macintosh programs, but you’re given the option to save a script in a number of formats: text, compiled script, or application. Saving it as text will allow you to open the code in any text editor such as BBEdit or Microsoft Word. This can be useful when you want more powerful text editing features than are available in Script Editor, such as search and replace. If you attempt to save a script that can’t compile because it has a bug, you’ll be told that you can only save it in text format.

A compiled script is saved with the code that it represents, and can be run only within Script Editor (or one of the third-party script editors). An application works just like any other application on the Mac OS. When you double-click it, instead of opening in Script Editor it will run with its own menus and memory area. Each format has a different icon so you can easily recognize it while in the Finder.

roll-04

The Various Script Editor Document Icons

When choosing to save your script as an application, you have some more choices to make. First of all, if you’re working in Mac OS 9, you can save the application either as a Classic Applet or a Mac OS X Applet. Also, you can opt to keep the script open after execution, which can be handy in many cases that we’ll go into later. Lastly, you can opt to show or hide the startup screen; if your script has a description, it will be shown with this startup screen.

There are two more windows available in Script Editor, both of which can be useful when debugging scripts. The first is the Result window, which you can show by selecting Show Result from the Controls menu or typing Command-L. The Result window shows the results of the last command executed by AppleScript. Take a look at the result window after running the following script and clicking “OK” in the appearing dialog box.

display dialog "Here’s a simple dialog."
roll-05

The Result Window

The last window is the Event Log window, which is also accessed from the Controls menu or by typing Command-E. This window shows a log of all the events that AppleScript processes. Events, in AppleScript lingo, are messages to an application. You can see from our screenshot of the Event Log that not only does the Event Log reveal which commands are events and where the events are being sent, but what the results of the events were. Notice that not every AppleScript command is an event (this event log was taken from the program we’re going to write after we introduce variables later in this column). Although there are three “set” commands in the script, as you’ll see later, none of them register in the event log.

roll-06

The Event Log Window

One last point about using Script Editor. Every AppleScript command must appear on one line. Writing code like the following won’t work:

display dialog
"Here’s a simple dialog."

Sometimes, however, AppleScript commands can be very long, and there is a need, for the human reader’s sake, to break the line into multiple lines. AppleScript provides a workaround for this. If an AppleScript line ends in a ¬ character, the next line is taken to be a continuation of the first. So, the above command could be written as

display dialog¬
"Here’s a simple dialog."

There are two ways to get the ¬ character in Script Editor. The first is to type Option-L (easy to remember, since the character looks sort of like an L). The second, and easier way to do it is to type Option-Return. This actually inserts two characters: the ¬ and a return, which is usually what you want anyway.

Now that we’re more familiar with our programming environment, let’s get back to our regular, well, programming.

Programs do their work by manipulating data, so programming languages provide a way to store and retrieve data. The tool for this is the variable. Variables are indispensable to programming. They allow the programmer to store a piece of information for later use. This information can then be altered or referenced elsewhere in the program.

A variable is simply a named piece of storage for your program. Variables can hold numbers, text, dates, or any other type of data. AppleScript, as in most areas of programming, makes it very easy to work with variables. To create a variable in AppleScript, we simply tell AppleScript to store a piece of data in a variable name that we provide. If you ever move to a lower level programming language, you’ll find that you have to declare a variable before it can be used, but this isn’t the case with AppleScript.

set myVariable to 9

The above line creates a variable called myVariable and stores the value of 9 in it. Any time we refer to myVariable in the rest of the program, it’s as if we used the number 9 instead.

set myVariable to 9
display dialog myVariable
roll-07

Displaying the Contents of a Variable

Given that the above display dialog line simply displayed a 9, why didn’t we simply use display dialog 9? Well, we could have, and in this case, using a variable doesn’t make much sense. So let’s take a look at a more complex example that takes input from the user, stores that input into a variable, and returns some data that was calculated based on the input.

If you recall from last month, we wrote a simple program that would tell us the sum of the numbers 1 through 5. But that’s not very flexible. Let’s expand the usefulness of that program just a little bit by asking the user how far we should sum. We’ll do that by using our familiar display dialog command to show a dialog box that allows the user to enter a number of his choice. We’ll store that choice in a variable and use the variable in our repeat statement.

display dialog "Please enter a positive number:"¬
    default answer "" buttons {"OK"} default button 1
set theNumber to the text returned of result
set sum to 0
repeat with i from 1 to theNumber
    set sum to sum + i
end repeat--Report the results of the process to the user.
display dialog "The sum of the first five number is " & sum &¬
     "." buttons {"OK"} default button 1

We’ve added something to our display dialog command in that first line: the default answer portion. This tells the display dialog command that we want a field to appear in the dialog where the user can enter information. We then get this information from a built-in variable of AppleScript’s called result. The result variable holds information returned by the display dialog command, specifically, the text entered by the user and the button clicked by the user. result in this case is of a special data type called a record, which we’ll cover in just a little while. For now, we just want the text entered by the user (the button must be the OK button since that’s the only one we specified). So by setting theNumber to the text returned of result, we are storing the user’s data into the theNumber variable.

The rest of the program should be familiar from last month. We enter a repeating loop that sets a variable called i to 1, incrementing it each time we go through the loop. Inside the loop we add the numbers, and then when the loop is finished, we report our calculations to the user.

As I mentioned before, variables can store many different kinds of information, such as text, numbers, and dates. While we won’t cover all of the data types AppleScript recognizes (there are over a dozen), we do want to make sure you understand the most common types. First there is the integer, which we’ve used already in our program above. An integer is a whole number, such as 7, 932, or 0. Integers don’t include numbers that have a fractional portion, like 7.2. That’s known as a real number, which is another data type of AppleScript. Real numbers are things like 0.3, 3.1415, or 11.0. Note that 11.0 is a real number, not an integer. To mathematicians, it may be an integer, but because it takes note of a fractional part, even though it’s zero, AppleScript defines it as a real number.

Text, also known as strings, consists of any group of characters enclosed in double quotes. The word “string” comes from the fact that text is a string of characters. Even if the characters are numerals, if they are enclosed in double quotes, AppleScript sees the numerals as a string. So, to give some examples, "Apple", "5", "About This Particular Macintosh" and "" are all examples of strings. That last one, two double quotes in a row, is an empty string, and believe it or not, it comes in quite handy in many programs.

For the most part, we’re going to use just those simple types of data, but there are two more complex types that we should cover now. The first is the list. A list is a group of individual pieces of data that are held together in a defined order. A list can hold any type of other data AppleScript provides, including other lists. Here’s an example of setting an AppleScript variable to a list of the first four prime numbers:

set thePrimes to {2, 3, 5, 7}

As you can see, a list is indicated by braces, and each item in the list is separated by a comma. This particular list includes only integers, but we could have a list like this:

set complexList to {9, "Chuck," pi, {2, 3, 5, 7 }}

This list has an example of each of the types of data we’ve covered so far. The first element of the list is an integer. The second is a string. The third is a real number (pi is a special variable provided by AppleScript that represents the mathematical constant). The last element is another list. Each of these can be referred to with the item operator.

set complexList to {9, "Chuck," pi, {2, 3, 5, 7}}
set myItem to item 2 of complexList
display dialog myItem
roll-08

Extracting an Element of an AppleScript List

The other complex data type that we will come in contact with on a regular basis is the record. We use the record often if for no other reason that the display dialog command returns a record after a dialog box is dismissed. A record looks a lot like a list, but each element of a record has a name. If you’re familiar with databases, a record is very similar to the kind you know already. Here’s an example of a record.

set theRecord to {firstName:"Chuck," lastName:"Ross," email:"This email address is being protected from spambots. You need JavaScript enabled to view it."}

Notice that a record looks a lot like a list, but each of the elements of the record has a name. We can get the value of each element like we did in our program using the result variable.

set theRecord to {firstName:"Chuck," lastName:"Ross," email:"This email address is being protected from spambots. You need JavaScript enabled to view it."}
set theName to firstName of theRecord
display dialog theName

If you remember when we received input from the user with the display dialog command, we got a record in the variable result. That record looked like this: {text returned:"10", button returned:"OK"}. Note that the text returned was actually a string, but we used it as an integer. When we placed the variable theNumber in our program inside of a repeat statement, AppleScript automatically translated the text entered by the user to a number that could be understood by the repeat statement. This assumes, of course, that the user didn’t enter something besides a number, such as “ten.” If it had, an error would have resulted when the program ran. Go ahead and try it if you like.

roll-09

Result of AppleScript Attempting to Coerce Text to a Number

In other words, when AppleScript expects something to be an integer, it tries to coerce it into that form. The string "10" is easily coerced into the number 10, but "ten" isn’t. Many programming languages don’t offer this ability to automatically coerce data from one type to another. Having the ability in AppleScript, while it may sound like only a good thing, is actually a tradeoff. It’s easier to write programs, but it’s also easier to make mistakes that bring a program to its knees, as you can see in the above screen shot.

When you’re unsure of what type of data a variable is storing, you can use the class of operator. This will return the data type of the variable.

set theVariable to "ATPM"
set theClass to class of theVariable
display dialog theClass
roll-10

The Class of a Text Variable as Reported by AppleScript

You can also manually coerce data from one type to another. AppleScript will do its best to convert the data, but some data can’t be coerced from one type to another. For instance, there’s no way to convert a list to a number (unless the list contains only one element and that single element can be converted to a number).

set theVariable to "100"
set theNumber to theVariable as number

After the above code is run, theNumber holds the number 100, not the string "100", because we specifically coerced theVariable to a number.

You may have noticed that I have an odd way of naming my variables. My variable names never have spaces, and the name seems to run together. This is a limitation of programming languages. Variables have to be a single word, so different programmers use different methods to make variables more easily understood. My method is to begin my variable with a lower case letter and begin each new word with an upper case letter. Others use upper case for every word, and others separate words with an underscore, like The_Variable.

AppleScript variables must begin with a letter or an underscore character, cannot have any spaces, and can’t use characters that AppleScript uses elsewhere (such as the plus sign). Variables also cannot be the same as any of AppleScript’s predefined words, such as repeat or set. This makes sense, since AppleScript would have no way to tell if you meant the command or the variable.

There is an exception to this (isn’t there always an exception?). If you begin and end your variable with the pipe character you can name your variable anything you like, even AppleScript reserved words.

set |set| to "ten"

Since AppleScript can use the pipe characters to know that you’re referring to a variable called set rather than the command set, you can use any name you want. You can include spaces or the plus sign and AppleScript will work fine. The truth is, however, I have never seen anyone use this method for naming variables, but it’s available to you if you like it.

That’s about it for variables and data types this month. I hope you’re enjoying our trip into programming. Thanks to everyone out there who has written in with suggestions and comments. Keep them coming! If you have specific programming questions you would like answered here next month, let me know. Do you have an idea for a program that you think would be great to build together in this column? Continue to send me your ideas and I’ll pick one or two that we can work out together. See you next month, when we’ll go over the exciting topic of program flow!

Add comment


Security code
Refresh

Search

Products