BYU Home pageBRIGHAM YOUNG UNIVERSITY
  Office of Digital Humanities
Back     BYU LiveCode Lessons Gateway

Digital Humanities & Technology 210

The LiveCode Scripting Language

The LiveCode scripting language, is a full-featured programming language with all the constructs of Java, C, and other common procedural programming languages. This reading will explain how LiveCode implements these basic constructs. Those who have experience with programming languages will recognize the similarities and differences.

Objectives

By the end of this reading you should be able to answer the following questions as they apply to LiveCode:

Variables

  1. What is a container?
  2. What is a variable?
  3. What is a script local variable, and how do you declare one?
  4. What is a global variable, and how do you declare one?
  5. What is the special variable it, and how is it used?

Constants and Literals

  1. What is a constant? Give several example.
  2. What is a literal value?
  3. How do you denote a literal value.

Arithmetic Operators

  1. What is an operator? Give an example.
  2. What are the main arithmetic operators?
  3. What is the order of precedence for evaluating arithmetic operators in LiveCode.
  4. What is the difference between the div and mod operators?

Commands

  1. What is a command? Give an example.
  2. Know several variations of the put command.
  3. Know several commands that perform basic arithmetic operations.

Functions

  1. Understand what a function is and how to use a function in a LiveCode statement.
  2. Know how to use the following functions: sqrt(), random(), date() and time().

Concatenation

  1. Know what concatenation means.
  2. Know how to build strings of text using the concatenation operators &, &&, and ,. Understand the differences in how these operators concatenate text strings.
  3. Know what the line continuation character ( \ ) is for.

Variables as Containers

Containers. Sometimes you may hear the term container used in LiveCode. A container is a storage location that has a name and can hold a value, such as a number or a string of characters. For instance, a LiveCode field has a name, and it can hold values or data, and so is a container. Using this definition, a variable is also a container. A variable is similar to a field in that it is a container for data, but it differs in that a field has a visible presence on the card, whereas a variable exists only in the computer’s memory. Thus the term container in LiveCode can refer to both variables and fields. Another way to think of it is that variables and fields are examples of a general class of things that are containers.

A variable called holder
with value "Hello world"

Virtually all programming languages make use of variables, and LiveCode is no exception. Variables are indispensable tools in programming, because they provide a way to store some value or information in memory until a handler needs access to it.

The concept of variables is not a difficult one—a variable is simply a named container that can hold a value. You can visualize a variable as a box in the computer’s memory with a name on it. The box can hold information, which can be referenced by its name. The box can hold any kind of data or information you need it to: strings of text, numbers, true/false values, even binary data.

There are a few simple rules for naming LiveCode variables. A variable name:

Creating Variables. In many programming languages you have to formally declare a variable and specify what type of data it can hold. Creating variables in LiveCode is a snap—you simply refer to it in a put statement:

  put "stuff" into holder

Here’s a breakdown of what each term in this statement does:

If you script it like this, the last word in the put statement—holder, in this example—will become a variable, and it will hold the value of the second word of the statement—"stuff".

Variables exist as soon as they are used as a variable. The first time you state the name of a variable in a put statement, the virtual box or container with that name is created. Once the variable has been created, you can use the name to put a value into the variable. You can also use the name to put the value the variable contains somewhere else.

  put 10 into myNumber
  put myNumber + 5 into field "sum"

Variables as Containers—An Illustration

Think of a variable this way: You’ve seen and used a trash can. It’s a container for things. Let’s create an imaginary trash can and call it "Oscar" (indulge me). If you put a newspaper into the trash can, the newspaper is still a newspaper. You can look inside the can and identify its contents as a newspaper. You can reach inside the can and pull out the newspaper and replace it with an apple core. Oscar now contains an apple core (which retains its identity as an apple core). If you place the newspaper into a different trash can called "Felix", it is still a newspaper. Throughout all this, the trash cans retain their names and you can still refer to them as Oscar or Felix (an odd couple), since the trash cans never lose their names or identities as containers even when their contents may change. At the end of our example, then, Oscar is holding an apple core and Felix is holding a newspaper (so apropos).

It’s the same way with a variable. If you have a variable and you name it holder for example, then you put "3" into that variable, the variable holder is just a container and inside it is the value 3. Putting 3 into the variable doesn’t change the value or nature of the 3 and it doesn’t change the variable’s name.

Variable scope and persistence

The term scope refers to where a variable and its value are recognized. Persistence refers to whether or not the variable and its value are preserved after a handler runs. Variables created inside a handler with the put command exist only while the handler in which it was created is executing. As soon as the handler finishes running, the variable and the value it contains disappear. That is, its scope is local to the handler and its persistence is temporary. The next time the handler is executed, the variable is created all over again, and it does not retain its value from the previous time the handler was executed. We refer to variables like this as temporary, or handler local variables. In the example below myNumber is a temporary, handler local variable:

  put 10 into myNumber
  put myNumber + 5 into field "sum"

Variable Scope—Handler-only, Local, or Global. Often you may want the value contained in a variable to persist beyond the scope of just a single handler. In order for a variable and its value to persist longer than the life of the handler, it must be declared as as either a global variable or a script local variable. Once created, these types of variables and their contents are retained after a handler has finished running.

Script local variables are accessible from any handler in the script where they are declared. Simply include this statement outside of all handlers in a script:

  local someLocalVar

  on handler1
    --do some stuff
    put "hello" into someLocalVar
  end handler1

  on handler2
    --do some other stuff
    put someLocalVar into field "result"
  end handler2

Once declared in the script, this variable and its value are accessible from any handler in the script. In the example above the value of someLocalVar is accessible between both handler1 and handler2. Assuming handler1 runs first, handler2 will put the text "hello" into the field.

Variable Scope—Global Variables. Global variables can be accessed anywhere in the stack where they are declared. Unlike a variable used only inside one handler, a global variable retains its value even after the execution of the handler that created it. Just as declaring a script local variable, declaring a global variable is simple:

 global someGlobalVar

A global variable must be declared and identified as such in every script that uses that global variable. Otherwise, the handlers that use the variable name will instead create temporary handler-only variables with the same name. For example, let’s say we have a field "start" with the number 12 in it. Button 1 has the following script:

  global holder

  on mouseUp   
    put field "start" into holder
  end mouseUp

Here is the script of Button 2:

  on handler2
    add 6 to holder
    put holder into field "result"
  end handler2

When Button 1 is clicked, the global variable holder is given the value of 12. This value is then accessible to all handlers in that script, and in any script where global holder is declared. Thus, after Button 2 is clicked (assuming Button 1 was clicked first) the value of holder, and of field "result", becomes 18.

Variable Scope—Handler-local Variables. Contrast this to the case where no global variable is declared. So the script of Button 1 would be:

  on mouseUp   
    put 12 into holder
  end mouseUp

Button 2’s script would be:

  on mouseUp
    add 6 to holder
    put holder into field "result"
  end handler2

In this case, holder has a value of 12 while Button 1’s mouseUp handler is running. But holder has a value of 6 after you click Button 2 (because it is adding 6 to nothing.) Unless the variable is declared as global (or local) outside of the handlers the variable and its value are temporary and limited in scope to the handler in which it was created.

Local and Global Variables inside a Handler. It is also possible to declare local and global variables inside a handler within a particular script. This would make the variable accessible only to the handlers in which the local or global variable is declared. For example:

  on mouseDown
    global holder
    put 12 into holder
  end mouseDown 

  on mouseUp
    add 6 to holder 
    put holder into field "result"
  end mouseUp

In this case, the global variable holder is available only to mouseDown (and any other script or handler in the stack that declare holder as global.) It is not available to mouseUp.

Both local and global variables and and their values disappear when the stack is closed and removed from memory. So the variable and its value would not persist if you quit LiveCode and restarted it, for example.

The special variable it

The LiveCode keyword it is a special-purpose variable that holds the results of the get command (and several other commands you’ll learn about later). It can help to make scripts more readable. However, you need to be careful, because the it variable doesn’t work the same as the pronoun "it" in English; that is, it doesn’t know what its antecedent is simply from context. You have to make sure something is in it before referring to it. For example:

Wrong:

  if there is a button "clickme" then
    put it into field "results"
  end if

Right:

  if there is a button "clickme" then
    get the label of button "clickme"
    put it into field "results
  end if

Constants and Literals

A constant is a named container, similar to a variable. However, as the term implies, the value of a constant is fixed and cannot be changed. Some constants make it fast and easy to refer to certain characters or values that are commonly used. Others simply provide enhanced readability in scripts.

Text constants: LiveCode defines several text constants to provide special characters that cannot readily be typed in directly.

Other constants: A number of other constants represent numeric and mathematical values, and can be used for convenience and readability:

Remember that these constants are not literal strings; they stand for their values, and so can be used as if those literal values had been typed into the command.

Literals

A literal is something that is the value itself. In LiveCode scripting, anything enclosed in double quotes is treated as a literal string; that is, the string inside the quotes is just what it is. This seems almost too obvious to discuss, but it is an important thing to understand, because of a quirk of LiveCode.

The use of quote marks becomes extremely important in keeping literals distinguished from variables. In LiveCode an unquoted string that has never been used as variable often—but not always—functions like a literal string. This can cause considerable confusion. Look at this handler, for example:

on mouseUp 
  show image flower
end mouseUp

LiveCode, attempting to be helpful, will try to figure out what the word ‘flower’ is. Since you have never used it as a variable, LiveCode will assume you meant it to be a literal value, and show the image object named "flower", if there is one. This might be alright and never cause a problem.

But what if your handler became much longer, and the show image statement was joined by many others? Then, months later, you come back and decide you need a variable at the top of your handler for some other reason. You decide that 'flower' makes a good variable name so you do this:

on mouseUp 
  put "petunia" into flower
  -- in the meantime, you have placed 
  -- lots more commands here, and you forgot
  -- that you had this statement:
  show image flower
end mouseUp

Now, suddenly, your handler that was reliably showing an image named "flower" is suddenly showing an image named "petunia", or more likely, producing an error because there isn’t any image named "petunia"! It is a good practice to always use quotes around the names of all objects when referring to them by their names, to avoid problems like this one.

Now let's consider the opposite situation, where you put quote marks where you don't intend them. Look at this handler:

on mouseUp   
  put "flower" into thisImage   
  show image thisImage
end mouseUp

This would take the literal string "flower" and place it within a variable called "thisImage." In referencing the variable on the very next line, the handler actually looks at the contents of the variable. Therefore, the handler would display an image called "flower." However, the handler would operate differently if one line were changed slightly:

on mouseUp   
  put "flower" into thisImage   
  show image "thisImage"
end mouseUp

Here the second command of the handler would try to display an image called "thisImage" since enclosing thisImage within quotation marks indicates that it is to be treated as a literal and not as a variable. Details matter!


Operators

Operator: An operator creates a relationship between the element on its left and the element on its right. You are probably most familiar with arithmetic operators. The symbols LiveCode uses as arithmetic operators are:

The rules of mathematics establish a standard order in which operations should be performed when there is more than one operator in a single statement. LiveCode follows the standard order of precedence in arithmetic operators you learned in algebra:

  1. exponentiation
  2. multiplication and division
  3. addition and subtraction

As in algebra, parentheses can be used to override default precedence.

Some operators are keywords rather than symbols:

We will see other types of operators later.


Commands

Commands are directives that usually result in some action being taken. Since LiveCode scripting is based on a human language, English, virtually all commands are in the form of verbs. We have already seen a few commands: go, show, and hide, enable and disable, wait, and beep. There are many more built-in commands in LiveCode, which are described and documented in the LiveCode Dictionary. Let’s take a closer look at a handful of commands.

Put: The put command is used to put values into containers. We have used this to put various strings into a field. We’ve also seen that it works essentially the same for variables. In this regard it is considered LiveCode’s assignment statement. The key words into, after, and before determine how the new value affects the existing contents of the container.

So far we have always specified a destination for our put command. It is also permissible to use put without a destination, like this:

  put "Hello World"

When you use put without a desination container designated after into, after, or before, LiveCode will display the result in the Message Box. This can serve as a quick and easy way of checking the value of a variable or the result of a put statement.

Techie note: The message box is what other programming environments often refer to as the standard output; that is, where the output of a command goes when there is no destination specified.

Arithmetic Commands: LiveCode provides four commands for common arithmetic calculations:

These commands perform the calculation on the value within the container and replace the value with the answer. For instance, these are all valid LiveCode statements:

  add 5 to field "value"
  
  subtract 10 from myvariable

  multiply myvariable by 2

  divide field "value" by 16

Few programming languages have arithmetic commands like these. Instead, they accomplish the same result with an assignment statement that references the variable in the calculation and assigns the result to the same variable. This technique also works in LiveCode. So you could do the same thing as above like this:

  put field "value" + 5 into field "value"

  put myvariable - 10 into myvariable

  put myvariable * 2 into myvariable

  put field "value" / 16 into field "value"

As you can see, in many cases the arithmetic commands make the statements shorter and easier to read.


Functions

A function takes some input, performs a predefined process on the input value and returns a modified value. Functions are always used within the context of a larger statement, never by themselves. A function can be used anywhere the value it returns is appropriate.

Forms: LiveCode functions generally have two forms:

Argument: An argument is the input value that the function operates on. Most (but not all) functions require at least one argument. In the example given above (sqrt(25)), the argument is 25. Arguments may be specified explicitly (as above) but can also come from a variable or a field or other source of value. For example, to find the absolute value of a number stored in a variable using the abs() function:

on mouseUp   
  global myNum   
  put abs(myNum) into field "Result"
end mouseUp

In this example, the argument passed to the abs() function is a variable. The function will perform its operations on the contents of the variable and place the result in a certain field. Obviously, the arguments passed to a function can vary and the values the function returns are dependent upon the arguments passed.

Commonly-used Functions

Here are some other useful functions. Remember that functions have two different forms.

random: This is a function that can often be used in instructional applications to provide variety and unpredictability. It returns a random value between 1 and the argument, inclusive. For example:

on mouseUp
  put random(20) into nextQuestion
end mouseUp

This handler would then put into nextQuestion any number between 1 and 20, the lowest possible value being 1, and the highest possible value being 20.

round: Rounds a number up or down according to standard rounding rules.

  put the round of 36.4  -- yields 36
  put round(36.446,2)  -- rounds to two decimal places; yields 36.45 
Here are two functions we’ve already seen. These functions don’t need an argument, since they simply get the information they need from the operating system. Note that they can use either form, but the “prose” form is the most common, as it is somewhat easier to read.

date: Returns the current date as set by the operating system.

  put the date
put date()

time: returns the current time as set by the operating system.

  put the time
  put time()

We will see many more functions later. You are welcome to explore and experiment with some of them. They are always identified as functions in the LiveCode Language Dictionary.


Concatenation

Concatenation means ‘linking things together’. In LiveCode the primary concatenation operator is the ampersand (&). It can be used in conjunction with a put statement to append one chunk of text to another.

The comma (,) is a special concatenation symbol in LiveCode. It appends pieces of text or numbers together, separating them by a comma. For example:/p>

  on mouseUp   
    put "Eeyore","Pooh Bear" into hundredAcreWood
  end mouseUp

This handler places the two strings together with a comma separating them (resulting in Eeyore,Pooh Bear) into a variable. This operator is an effective tool for concatenating several strings into a single comma-delimited string.

Concatenation—What’s it Good For?

Of course, just concatenating literal strings together makes little sense. After all, you can more easily just put them into the same string to begin with. The real power of concatenation lies in the ability to combine literal strings with variable values to create more “dynamic” texts strings. For example, let’s say we want to have a field on all of the cards in our stack that reports which card you are on. You might put a handler similar to this in the stack script:

  on openCard
    put the number of this card into currentCard
    put the number of cards into totalCards
    put "Card" && currentCard && "of" && totalCards \
       & "." into field "counter"
  end openCard

You will rapidly see how useful concatenation operators can be.

The Line Continuation Character

As long as we are talking about special symbols, let’s look at the \ symbol. This is a special symbol that functions as a line continuation character in the LiveCode script editor. If a line is too long to fit conveniently in the script editor window, you can use the \ character to break it into two or more lines for easier viewing. You’ll often see this character used in these lessons to keep lines in example code to a reasonable length. A line split with \ is treated like a single line when a script is executed.

  put "A very, very, very, very long sentence." \
    into field "myField"

Note, however, that a \ character inside a quoted literal string does not break the line, because it is considered part of the quoted string. If you want to break a line inside the quoted string, you have to break the quote up into two parts and concatenate the two parts, like this:

  put "This is much, much, much, much longer" \
    & " than the other one." into field "myField"

Back     BYU LiveCode Lessons Gateway
Maintained by Devin Asay.
Copyright © 2005 Brigham Young University