Computer languages tend to be simpler and more rigid than human languages, but like any other language Lingo has a set of rules that control the structure (syntax) of your Lingo program. Just as languages have grammar, Lingo’s syntactical rules restrict the spelling, vocabulary, and punctuation so that Director can understand your instructions.
Tip
A syntax error or script error usually indicates a typographical error or the incorrect use of a Lingo statement.
Lingo’s built-in keywords (or reserved words) make up Lingo’s vocabulary and are the building blocks of any Lingo program. We’ll see later how these keywords form the skeleton of your Director program, just as any language’s words are the basis for sentences and paragraphs. It is crucial that you recognize which items in a Lingo script are built-in keywords versus those that are specified arbitrarily by the programmer. Refer to Chapter 18, Lingo Keyword and Command Summary, for a complete list of all Lingo keywords. The PrettyScript Xtra (http://rampages.onramp.net/~joker/tools/) is a $20 U.S. shareware tool that colorizes some items in your Lingo scripts to make them easier to recognize. The ScriptOMatic Lite Xtra, is available under XtrasScriptOMatic
➤Lite, colorizes a broader range of items, but it is crippled almost to the point of being useless. The full version is promised imminently from g/matter (http://www.gmatter.com/products/scriptomatic/) at press time.
A handler is a series of Lingo statements that tell Director to perform some useful function. Handlers are typed into script cast members in the Script window. (“Script” is also used loosely to refer to a handler within a script. “Code” is used both as a noun to indicate your Lingo scripts and as a verb, meaning “to program” or “to write Lingo scripts.”)
The scripts in a Director movie control the action, just as real-life actors follow a script. There are several types of scripts (castmember scripts, movie scripts, sprite scripts, parent scripts, and Behaviors), which are covered in detail in the "Lingo Scripts and Handler Types" section of Chapter 2.
As required by the International Programmers’ Treaty of 1969, we’ll start with an example that displays “Hello World.” Open up a movie script cast member using Cmd-Shift-U (Macintosh) or
Ctrl-Shift-U (Windows).
Enter Example 1-1 exactly as shown into the movie script window.
The keyword on
identifies the beginning of our handler, which we arbitrarily chose to name helloWorld
. The keyword end
signifies the end of our handler.
Tip
The examples beginning with the word on
are handlers that must be typed into a script, not the Message window.
With minor exceptions, your Lingo code for each handler goes between the on
handlerName
and end
commands (see "Where Commands Go“).
Handler names must be one word, but they are case-insensitive, so you can use capitalization to make them easier to read. Name your handlers descriptively so that you can remember what they do, and as a rule you should avoid naming them the same as existing Lingo commands (see Table 18-1).
A handler name must start with an alphanumeric character, not a digit, but it can contain digits, decimal points, and underscores. Only the first 260 characters of the name are significant.
Movie script cast members are simply repositories for our handlers and are not used in the Score (see Chapter 2 for details on score scripts).
Entering a handler into a script (as shown above) defines or declares the handler and is referred to as a handler definition. Defining (declaring) a handler makes it available for future use, but the handler doesn’t execute until something tells Director to run it for you.
Close the Script window to compile it (that is, to prepare it to run). When the handler is run (called), Lingo will execute each line (that is, each command) in the order in which it appears in the handler. There is only one command in our helloWorld
handler; the built-in alert
command displays the specified text in an alert dialog box.
The Message window provides an area for printing messages from Lingo and testing Lingo scripts (see Chapter 3, Lingo Coding and Debugging Tips). A handler stored in a movie script can be executed (called) by typing its name in the Message window (or by using its name in another handler).
Open the Message window using Cmd-M (Macintosh) or
Ctrl-M (Windows). In the Message window, type the name of the handler to test (helloWorld
without any spaces). Do not precede the name with the word on, which is used only to declare a handler, not to run it.
helloWorld
Tip
Always press the RETURN key (Macintosh) or the
ENTER key (Windows) at the end of the line to initiate the command. Example code shown flush left should be typed into the Message window, as opposed to handler definitions that are entered in the Script window.
Congratulations, you are now a Lingo programmer! After accepting your diploma, please step to the right. If your script didn’t work, make sure you typed everything correctly and that you entered the script in a movie Script window (not a score script, castmember script, field, or text cast member). Choose Control
➤Recompile
All Scripts. If it still fails, hang your head in shame, or see Chapter 3 and Chapter 4.
Typing helloWorld
in the Message window calls (locates and runs) the handler of the same name. Reopen the script, and change both the name of the handler in the script and the name you type in the Message window to something new. If the names don’t match, what happens? Did you remember to recompile the script by closing its window? Set the Using Message Window Recompiles Scripts option under Preferences
➤General
to ensure that the latest version of a handler is executed. See "Compiling Scripts" later in this chapter.
Note above that "Hello World
" is automatically incorporated by the alert
command into the alert dialog. You can change the displayed text by specifying any string (series of characters) in place of "Hello World
" (don’t forget the quotes). The specified string is said to be an argument to the alert
command, and it is used to customize the dialog. See "Commands and Functions" and "Parameters and Arguments" later in this chapter for complete details on using arguments with built-in Lingo commands and custom handlers.
Previously we created an arbitrarily named custom handler and called it from the Message window by using its name.
Tip
You can add more handlers after the end of the helloWorld
handler in the movie script used above, or you can press the “+” button in the Script window to create a second movie script. (You can have a virtually unlimited number of movie scripts).
Naturally, the user will not be typing anything in the Message window. When the user clicks the mouse button or presses a key Director tries to run handlers named on mouseDown
, on mouseUp
, on keyDown
, and so on. In practice, you’ll create event handlers with these reserved names to respond to user events. If you name the handlers incorrectly, they will never be executed. See the "Events" section in Chapter 2, and Chapter 9 for more details.
Just as we can call a handler from the Message window, one handler can call another simply by using its name. As each handler completes its work, control returns to the calling handler. You can picture a hierarchy of nested handler calls as an outline that periodically is indented further, then returns to the previous level. Suppose we define several handlers (some of which call other handlers) in a movie script as shown in Example 1-2.
Tip
The put
command prints a message in the Message window and is used throughout the book to peek inside Lingo. The &&
and &
operators are used to assemble long strings (see Chapter 7, Strings). Lingo lines starting with two hyphens (“—”) are comments for the reader’s benefit (see "Comments,” later in this chapter).
We can then test it from the Message window.
handlerA -- "I'm in handlerA" -- "I'm in handlerB" -- "I'm in handlerD" -- "I'm back in handlerB" -- "I'm back in handlerA" -- "I'm in handlerC" -- "I'm back in handlerA one last time"
Tip
The series of Lingo handlers that are currently “pending” is known as the call stack. The call stack is always shown in the upper left pane of the Debugger window (see Figure 3-1).
Note that handlerA
calls handlerB
, which then calls handlerD
. Control then passes back through handlerB
and back to handlerA
. Finally, handlerA
calls handlerC
, and control is then returned to handlerA
. Conceptually, this can be pictured as:
handlerA handlerB handlerD handlerC
Note that the order of execution within a handler is determined by order of the Lingo commands, but the order in which the four handlers are typed into the movie script is irrelevant. Execution begins at our so-called entry point (in this case handlerA
, which was called from the Message window), and Lingo takes detours into each called handler before it returns control to the calling handler. Note that handlerE
is never called and therefore never executed, even though it has been defined in the same script with our other handlers.
Each time a handler is called, a copy of it is created temporarily. The copy comes into existence when the handler is called and disappears when the handler completes. You can call a handler hundreds of times, and each occurrence will be independent of the other occurrences. A handler that calls itself, as shown in Example 1-3, is called a recursive function, and this technique is called Recursion.
Warning
If we call our recursive function from the Message window, Director will run out of memory. (Save your work before testing this as it may crash your machine.)
Example 1-3. A Recursive Function
on recurseTest recurseTest put "End of recurseTest reached" end recurseTest
If you are using recursion, it is probably an accident. As a general rule, you should avoid it. It is like a reflection repeated infinitely between two mirrors; in the extreme case it will crash Director. See Example 6-9 in Chapter 6, Lists, Example 8-16 in Chapter 8, Math (and Gambling), and Example 14-5 in Chapter 14, External Files, for proper uses of recursion.
Even if we call recurseTest
only once, it calls itself repeatedly so that Director keeps going “down” an extra level and never comes back up for air. Director will run out of memory before the put “End of recurseTest reached” command is ever reached. Note that each time recurseTest
is called, it spawns another copy of itself. Conceptually, this can be pictured as follows:
recurseTest
recurseTest
recurseTest
recurseTest
(ad infinitum until Director runs out of memory)
Note that it is perfectly acceptable for one handler to call another repeatedly, as is often done using a repeat
loop (see "Repeat Loops" later in this chapter).
Example 1-4. Calling a Function Non-recursively
on testIt repeat with i = 1 to 100 someHandler end repeat end on someHandler put "I am inside someHandler" end
Typing testIt
in the Message window will print out "I am inside someHandler" 100 times with no ill effects because each time someHandler
completes, control is returned to the top level (in this case, the testIt
handler).
There is no magic to entering Lingo scripts. Scripts are typed in script cast members (or attached to non-script cast members) via the Script window. Script cast members appear in the Cast window along with your other assets (bitmaps, fields, and so on). The Script and Message windows include buttons to access pop-up menus of Lingo commands (both alphabetical and by category). You can use these to insert commands into your scripts or to remind you of the correct syntax. Refer to Chapter 2 of this book and to Chapter 2, Script Basics, of Macromedia’s Learning Lingo manual for details on creating scripts and entering your Lingo.
All your Lingo code goes between a handler’s on
handlerName
and end
statements.
The exceptions to the rule are:
Each handler should be separate from other handlers. Handler declarations are not “nested” the way that
if...then
statements can be. Do not start a new handler beforeend'ing
the first one, as described under "Common Handler Declaration Errors" later in this chapter.Comments can be placed both inside and outside handlers.
Property variables must be declared outside any handler.
Global variables can be declared both inside and outside handlers. Global variables declared within a handler apply only to that handler. Global variables declared outside a handler apply to all handlers in the script following the declaration.
Each Lingo command occupies its own line (although there are some multiline Lingo statements, discussed under "Multiline Code Structures" later in this chapter). Each line of Lingo is separated using a carriage return—that is, using the Return
key (Macintosh) or Enter
key (Windows) on the main keyboard, not the one on the keypad.
You can enter long lines of Lingo code in your script without line breaks; Director will wrap them automatically. To improve readability (as with many examples in this book), long lines of Lingo code can be continued onto the next line using the Lingo continuation character ¬, as shown in the example that follows. This special character is created using Option-Return
(Macintosh) or Alt-Enter
(Windows).
-- Here is a long line of Lingo broken onto two lines
set the member of sprite (the currentSpriteNum) = ¬
member "Hilighted Button"
You can break long lines of Lingo onto more than two lines using an ¬ character at the end of each line (except the last) of the long command. Do not break the long lines (that is, do not use the ¬ character) within quoted strings (see Chapter 7, Strings). Do not put anything, even a space, on the same line after a continuation character.
Director ignores leading spaces and automatically indents your Lingo code according to its own rules. For example, all lines within a handler between the on
and end
statements are indented at least two spaces. Use the same font and type size throughout the script to make the code more legible and indentation problems obvious. Colorized or formatted text can slow the Script window’s response, especially for longer scripts. A single script cast member is limited to 32,000 characters, but you can use as many script cast members as required.
Warning
Use the Tab key
to automatically indent your Lingo code. If the indentation is wrong, you may have omitted necessary keywords or used them in the wrong order. Refer to "Lingo’s Skeletal Structure" later in this chapter.
The Lingo code you enter is simply text (although you should enter it in a script cast member, not in a text or field cast member). Before it can be run, Director must compile your Lingo code into a machine-readable format. (This is analogous to a player piano, which cannot read sheet music but can play a song if is transcribed onto a paper roll.)
When Director compiles a script, it checks that the syntax conforms to the accepted rules and does its best to parse (understand) the structure of your Lingo. Compilation is analogous to spellchecking and grammar checking in a word processor. It merely checks that your Lingo code has a recognizable structure and acceptable keywords. It does not attempt to actually run your Lingo code.
It would be counter-productive for Director to attempt to compile your scripts as you type them. Use Control
➤Recompile All
Scripts to compile your scripts when you finish typing (see "Compiling Scripts" in Chapter 2).
If Director’s compiler fails, it displays a script error (a syntax error) that identifies the offending portion of the Lingo, but it may merely reflect a problem that lies elsewhere. You would then correct the Lingo and recompile. If successful, it creates a hidden compiled version of your Lingo script that runs more quickly than it would if Director had to reinterpret your human-readable script every time it runs.
If compilation succeeds, your code is not necessarily error-free and may still cause a so-called runtime error when Director attempts to run it. (In this context runtime refers to when the script is executed, as opposed to when it is compiled. This should not be confused with authoring time (in Director) vs. runtime (in a Projector). Refer to Chapter 3 for more details.
Handlers are stored in script cast members (excepting those attached directly to other member types); the multiple types of script cast members are explained in great detail in Chapter 2. The script cast member’s type (movie script, score script, or parent script) affects the scope of all the handlers declared within it (that is, which other scripts can “see” these handlers and from where they are accessible). We were able to test the example handlers above from the Message window because they were entered in movie scripts. (A movie script is a script cast member whose type is set to Movie in the script cast member’s info window). Handlers in movie scripts can be “seen” from the Message window or any other script in the same Director movie (even from scripts in other linked castLibs) because they have universal scope.
Had we entered the example handlers in score scripts, attempting to use them from the Message window would result in a "Handler not defined" error because the scope of score scripts is more limited.
If two handlers in the same script cast member have the same name, Director will complain. Neither should you use two handlers with the same name in two different movie scripts because the first handler found will intercept all function calls using that name, and the second handler will always be ignored.
Tip
Place any handlers that you use in multiple Director movies or multiple Director projects into movie scripts in an external cast library that you can link into your project. Use unique names, perhaps starting with a prefix such as "lib,” that are unlikely to conflict with other handlers in a given movie.
Avoid naming your handlers the same as existing Lingo commands (see Table 18-1). A custom handler (stored in a movie script) that has the same name as a built-in Lingo command will intercept (and override) any calls to that Lingo command. If accidental, such an error can be extraordinarily hard to debug.
Contrary to movie scripts, it is very common to use handlers of the same name in score scripts. (Again, these are explained in detail in Chapter 2.) The important point is that the handlers in score scripts have a different scope (accessibility) than handlers in movie scripts. For example, most sprite scripts (one type of score script) will contain on mouseUp
handlers, and most frame scripts (another type of score script) will contain on exitFrame
handlers. The same handler name can be used in multiple score scripts because they do not have universal scope as do handlers in movie scripts. Director automatically calls only those handlers that are attached to the current frame or the sprite on which the user clicked. Other on mouseUp
and on exitFrame
handlers located in other score scripts won’t interfere. Refer to Chapter 9 for more details. Likewise, Lingo calls an on keyDown
handler only if it is attached to the field sprite that has keyboard focus (see Chapter 10).
Example 1-5 demonstrates the different scope of a handler depending on the script type in which it exists.
If the following two handlers coexist in the same score script cast member, handlerA
can call handlerB
(or vice-versa).
Example 1-5. Handler Scope
on handlerA handlerB end on handlerB put "I am doing something, so please stop hovering." end
If the two handlers existed in two separate score scripts, however, they would not “see” each other and therefore could not call each other. On the other hand, if handlerA
was in a score script, but handlerB
was in a movie script, handlerA
could call handlerB
, but not vice-versa. Furthermore, if handlerB
is in a movie script, it can be called from other handlers in other scripts of any type. Therefore, you should place one copy of your general-purpose utility handlers in a movie script rather than replicating it in multiple score scripts.
Tip
Handlers in movie scripts can be called from anywhere at any time and are usually custom handlers named arbitrarily by the programmer. Handlers in score scripts are generally named to respond to predefined events (such as mouseUp
) and are called by Director in response to those events.
This example offers a simplified picture of the universe. In actuality, any handler in any script can be called from anywhere if you refer to the script explicitly. You usually refer only to the handler name and let Director decide in which script to find the handler. This is covered in Chapter 2, along with details on the way that handlers in multiple scripts are sometimes called in succession.
See "Special Treatment of the First Argument Passed" later in this chapter for details on how the first argument to a function affects which scripts are searched for a matching handler.
A command tells Director to do something, such as play a sound, but usually does not return any result. Built-in Lingo keywords are referred to as commands, but you can create custom handlers that are used just like the built-in commands, essentially extending Director’s command set. (The word command is also used loosely in many contexts, including to indicate a menu choice.)
The general format of a command is:
commandNamearg1
,arg2
,arg3
, ...
where the arguments (arg1
, arg2
, arg3
, ...) are inputs used by the command, and may be optional or mandatory, and vary in number and type depending on the command. For example, the alert
command shown previously expected a single string argument. The puppetSprite
command expects two arguments (an integer and a Boolean value), as in:
puppetSprite 17, TRUE
A command that returns a result is called a function (the terms, though, are often used interchangeably). The result may be a number, a string, or any other data type. The general format of a function is
setvariableName
=functionName
(arg1
,arg2
,arg3
, ...) or putfunctionName
(arg1
,arg2
,arg3
, ...) intovariableName
where again the arguments (arg1
, arg2
, arg3
, ...) may be optional or mandatory and may vary in number and type depending on the function.
For example, the power()
function requires two arguments and raises the first argument to the power specified by the second argument. You wouldn’t ordinarily compute a value and discard the result; you would either print it out in the Message window or store it in a variable (a container for data). Below, the result of the calculation is stored in a variable that is arbitrarily named myValue
(see "Variable Storage Classes and Data Types" later in this chapter for details on variables).
set myValue
= power (10, 2)
If you don’t store the result in a variable, the function still returns a result that can be used in other expressions (see Chapter 5, Data Types and Expressions). This prints the result in the Message window instead of storing it in a variable:
put power (10, 2) -- 100.0000
This uses the result of the calculation to decide whether to print a message:
if power (10, 2) > 50 then put "That's a big number."
In some cases, Director issues a "Command not defined" error if you use a function by itself rather than as part of a larger expression:
power (10, 2) -- This causes an error
Either use put power (10, 2)
to print the result of the function call in the Message window or assign the result to a variable, as shown earlier.
If a function does not require any arguments, you must still include the parentheses to obtain the result, such as:
put browserName() -- "Mac HD:Netscape Navigator Folder:Netscape Navigator"
See "Return Values and Exiting Handlers" later in this chapter for details on returning values from custom handlers.
Lingo allows nested function calls, in which the result of one function is used as an argument to another function, such as:
if (random(max(x
,y
)) > 5) then ...
In such a case, the result of max(x, y)
is used as an argument to the random()
function. The preceding code is just shorthand notation for:
set myValue = max(x
,y
) if (random(myValue) > 5) then ...
This section is next in the logical progression of the chapter, but it will not make sense unless you understand concepts explained later. You can skim it now and revisit it after reading the rest of the chapter. As alluded to earlier, a handler often performs a calculation and returns the result to the calling routine. A handler or Lingo command that returns a value is called a function. Most functions require some inputs on which to operate (see "Parameters and Arguments" for details). For example, the built-in Lingo function max()
returns the maximum value from the list of items you send it:
put max (6, 9, 12) -- 12
You might write your own custom function that returns TRUE or FALSE based on whether the input is a valid digit between 0 and 9, as shown in Example 1-6.
Example 1-6. Returning a Value from a Function
on isDigitsomeChar
if "0123456789" contains string (someChar
) then return TRUE else return FALSE end if end isDigit
In this case, the result (1) signifies the Boolean value TRUE
:
put isDigit (5) -- 1
Warning
The parentheses surrounding the arguments are mandatory when calling a function that returns a value. Even if the function does not require any parameters, you must still include the parentheses to obtain a result.
If the parentheses are omitted, Lingo would treat isDigit
as if it were a variable name (see "Variables and Properties" later in this chapter) rather than a function name. In the following case, isDigit
is mistaken for a VOID
(valueless) variable, and the put
statement prints the values VOID
and 5 instead of the desired result of the function call.
put isDigit 5 VOID 5
Note the use of parentheses following rollover():
put rollOver() -- rollOver() is treated as a function call -- 7 put rollOver -- rollOver is treated as a variable name -- VOID
Ordinarily a handler terminates when the last statement in it is reached (the end
statement). Control then returns to whatever called the handler (either another handler or Director itself). In that case, no value is returned to the calling handler, and any calculated result would be lost unless it were stored in a global or property variable. The return
and result
commands obtain return values from a handler. The abort
and exit
commands terminate a handler prematurely. (They differ from next repeat
and exit repeat
, which affect program flow but do not exit the handler). The quit
, halt
, restart
, shutDown
, go
, play
, play done
, and pass
commands may also affect the order of Lingo execution.
-
return
The
return
command exits the current handler and returns control to the calling routine, along with an optional value of any data type. Any statements following thereturn
are not executed, which makesreturn
convenient for exiting a handler once a particular condition is met or task is completed.Example 1-7 returns as soon as it finds a sound cast member in the primary castLib. It returns zero (0) if no sound cast member is found. The other details are not important at this point.
Example 1-7. Returning Prematurely from a Function
on findFirstSound -- Loop through the cast repeat with n = 1 to the number of members -- Look for a sound castmember if the type of member n = #sound then -- Return the number of the sound -- and we're out of here! return n end if end repeat -- If no sound was found, return 0 return 0 end findFirstSound
Test it in the Message window:
put findFirstSound() -- 72
Warning
The above technique is best used with small handlers. Avoid using multiple
return
statements to exit a large handler from many different points. It makes the code harder to understand and maintain. Storing the eventual return value in a variable and returning it at the end of the handler is often clearer.You can use
return
without a value, in which case it is identical toexit
, and the caller receivesVOID
as the returned value. Note that thereturn
command is distinguished by context from theRETURN
constant (which indicates the carriage return character).-
the result
The result
retrieves the result of the last function call, even if it was never stored in a variable when it was returned by the last function call.set x = isDigit (5) put x -- 1 isDigit (5) put the result -- 1
Some commands, such as
preLoad
andpreLoadMember
, do not return a value, but setthe result
.preLoadMember 1, 5 put the result -- 5
-
abort
Abort
aborts the call stack (that is, the current Lingo handler and any handlers that called it) without executing any of the remaining Lingo statements in any of those handlers. By contrast,exit
exits only the current handler.Abort
is useful when you want to stop the current action in response to some drastic change. For example, if the user presses theEscape
key, you may abort what you are doing:on getUserInfo -- Abort if the user hits ESCAPE (ASCII code 27) if the key = numToChar (27) then abort end if end getUserInfo
Abort
does not quit Director (seehalt
orquit
), nor does it abort asynchronous operations in progress (seecancelIdleLoad
,netAbort
).Abort
aborts only Lingo execution; it does not affect the Score’s playback head (see thepause
command).-
exit
Exit
(not to be confused withexit repeat
) causes Lingo to exit the current handler. It exits “up” only one level to the calling handler, as opposed to aborting the entire call stack (see "Nested Function Calls" earlier in this chapter). Exit is often used to exit the current handler if some condition is not met:on playVideo if not (the quickTimePresent) then alert "You can't play video without QuickTime." exit end if -- Remaining statements are run only -- if QuickTime is installed. end playVideo
When using
exit
, no return value is sent. Usereturn
instead to return a value to the calling handler.quit
,halt
,restart
, andshutDown
Quit
andhalt
immediately quit a Projector and are generally used only in a script attached to a Quit button or at the end of a presentation. During development,halt
stops the movie without quitting Director. See Chapter 8, Projectors and the Run-time Environment, in Director in a Nutshell for details on these and other commands, includingrestart
andshutDown
.-
go
The playback head moves semi-independently remaining of Lingo commands. If you use the
go
command to move the playback head, commands in the handler are still executed before jumping to the new frame.on exitFrame
go frame 50
put "This will be printed before jumping to frame 50"
end
play
andplay done
The
play
command works differently than thego
command. Commands following theplay
command are executed, but not until aplay done
command returns control back to the original script. Commands followingplay done
are never reached. Test this using a frame script of the form:on exitFrame play frame 50 put "This will be printed second, not first" end
In frame 50, use this frame script to complete the test:
on exitFrame
put "This will be printed first"
play done
put "This line won't ever be reached or printed"
end
-
pass
The
pass
command aborts the call stack (see theabort
command). Commands following thepass
command are never executed. Control immediately jumps to the next script that handles the event being passed (see Chapter 2). For example:on mouseUp pass put "This line won't ever be reached or printed" end
This section is next in the logical progression of the chapter but is fairly advanced—and irrelevant for most users. You can skim it or even ignore it altogether without significant regret. You can create new Lingo dynamically at runtime (that is, while Director or even a Projector is running). Using the do
command or by setting the scriptText of member
property, you can actually create new Lingo from within Lingo! You can dynamically evaluate a string as if it is a Lingo statement using the value()
function. Most programming languages don’t allow this, and you will rarely use this feature. The following examples are for illustration only and do not necessarily depict likely uses.
The do
command can compile and execute a string on the fly as if it were a Lingo statement. Although it should not be used haphazardly, it can perform some interesting tricks. Most notably, you can use it to execute an arbitrary command stored in a text file or a field cast member. You can create a pseudo-Message window for debugging Projectors by do
‘ing the text entered in a field cast member:
do "beep" do the text of field "someFieldCastMember"
You cannot use do
to declare global variables without a trick. The following will not work:
do "globalgSomeGlobal
" do "setgSomeGlobal
= 5"
To declare a global with a do
statement, use:
do "globalgSomeGlobal
" & RETURN & "setgSomeGlobal
= 5"
To make use of a global within a do
statement, declare the global inside the current handler. So-called “global globals” declared outside the currrent handler are not recognized during a do
statement. The following example is illustrative only and would never be required in reality:
on setGlobal global gSomeGlobal do "set gSomeGlobal = 7" end
The value()
function can be used to convert a string into an integer or a float, as is useful when converting string data from a file or user input into a number.
set userEntry = value (field "Age in Years")
Value()
can also evaluate a string or symbol as if it is a variable name:
set someVar = "Oh happy days!" put value ("someVar") -- "Oh happy days!" put value (string(#someVar)) -- "Oh happy days!"
The scriptText
of member property contains the Lingo code from a script cast member. The human-readable form of the scriptText
is stripped when creating Projectors and protecting DIR files (creating DXR files), leaving only the hidden internal compiled version. Even from a Projector, you can create a script dynamically, as shown in Example 1-8.
Example 1-8. Creating Scripts at Runtime
-- Set up a string variable containing the text: on createscript set dynaScript = "on newHandler" & RETURN ¬ "global gMyGlobal" & RETURN ¬ "set gMyGlobal to 52" & RETURN & "end" -- Create a new movie script cast member, and fill it in. set newMovieScriptCastMember = new(#script) set the scriptType of newMovieScriptCastMember = #movie set the scriptText of newMovieScriptCastMember = dynaScript end -- Now you can run it createscript newHandler -- If desired, you can then delete the cast member erase newMovieScriptCastMember
Get Lingo in a Nutshell now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.