Serious First Steps In UserTalk Scripting
by Matt Neuburg
Author of the book Frontier: The Definitive Guide

Prev | TOC | Next


The Handler Rule

The eponymous handler

What I call "the handler rule" has to do with the relationship between a script and its "eponymous handler".

(You like that term? I made it up. Hey, I wasn't a Classics professor for 15 years for nothing, you know! However, it has now, I think, become generally accepted, probably because it is exactly the appropriate expression for something that previously had no name.)

A script's eponymous handler is the "on" line defining the verb whose name is the same as that of the script object itself -- for example, in workspace.counter, the line "on counter()" introduces the script's eponymous handler, because the script object and the handler are both named "counter".

The handler rule comes in two parts:

The Handler Rule, Part 1

A script doesn't have to have an eponymous handler at all, just in case the verb it defines takes no parameters.

Well, our verb counter() does take parameters. So we are required to use an eponymous handler in the script.

We can, however, rewrite workspace.counterCaller to have no eponymous handler; just make it consist of one single line, like this:

workspace.counter ( 10, 7 )

Press the Run button. Sure enough, workspace.counterCaller still works; it calls counter(), as before, counting down from 10 to 7.

The Handler Rule, Part 2

When you press a script's Run button, the top-level commands in the script execute.

But when, from one script, you call another script that has an eponymous handler, it is the eponymous handler that executes; the top-level commands of the called script are ignored.

Part 2 of the handler rule tells us that when, in workspace.counterCaller, we call workspace.counter(), Frontier will jump right into the counter() handler of workspace.counter; the last line of workspace.counter, which is at top level (it is outdented as far to the left as it can be), will be ignored.

To confirm this, change the last line of workspace.counter to this:

counter ( 1, 3 )

Press the Run button, and counter() counts from 1 to 3. Now press the Compile button, and go into workspace.counterCaller, which still says this:

workspace.counter ( 10, 7 )

and press the Run button; the counter() eponymous handler counts from 10 down to 7. The last line of workspace.counter is being ignored.

Stubs

This way of doing things has great advantages when you want to test a verb you're in the process of creating.

If your script contains an eponymous handler, the script can contain the verb itself (the eponymous handler) plus anything else you care to put into the script.

This "anything else" can be a test, or series of tests, designed to make sure that your verb works correctly. The test executes when you push the Run button, but not when you call the script from another script.

To see that this is so, let's modify workspace.counter so that it allows us to test counter() for any parameters we care to supply. Change workspace.counter so that it looks like this:

on counter (lowerLimit = 1, upperLimit = 10)
    if lowerLimit < upperLimit
        for n = lowerLimit to upperLimit
            msg (n)
            clock.waitseconds (1)
    else
        for n = lowerLimit downto upperLimit
            msg (n)
            clock.waitseconds (1)
if dialog.getInt("Count from?", @fromWhat) \
and dialog.getInt("Count to?", @toWhat)
    window.about()
    counter(fromWhat, toWhat)

Run this by pressing the Run button. You can see that we've created a testing interface, which puts up dialogs to let us enter numbers to count from and to, and then tells counter() to count.

Play with it for a while, pressing the Run button and supplying various numbers. Now press the Compile button, and then go to workspace.counterCaller and press the Run button there. The dialogs never appear; counter() just counts from 10 down to 7, because that's how workspace.counterCaller calls it.

In workspace.counter, the "if...and" lines we just created are at the top level (and the next two lines are indented below them, so they are part of the "if"); hence these are not executed when we call workspace.counter() from another script. They are executed only when we press the Run button within workspace.counter itself.

A testing milieu such as we have just created for workspace.counter is called a stub, and one of the nice features of UserTalk is that it makes it easy to write stubs without their getting in the way of the basic functionality of the verb you're developing.

Mopping up

In the stub we've just written, several interesting features of UserTalk were introduced. We used a couple of verbs, dialog.getInt() and window.about(), which represent classes of verb (dialog verbs and window verbs) capable of controlling interface elements of the Frontier environment as a whole.

Indeed, from a script, you can make Frontier do just about anything you could do manually, and more besides. We'll see some more examples later in this tutorial.

We also split a single line into two by ending the first with the backslash character. It would have been equivalent to put the whole "if" expression on a single line, like this:

if dialog.getInt("Count from?", @fromWhat) and dialog.getInt("Count to?", @toWhat)

But as lines get long in a script they can get hard to read, so it is convenient to be able to split them in this way.

Also, we used the "@" character. This is explained in the next chapter.


Prev | TOC | Next

All text is by Matt Neuburg, phd, matt@tidbits.com.
For information about the book Frontier: The Definitive Guide, see my home page:
http://www.tidbits.com/matt
All text copyright Matt Neuburg, 1997 and 1998. ALL RIGHTS RESERVED.
No one else has any right to copy or reproduce in any form, including electronic. You may download this material but you may not post it for others to see or distribute it to others without explicit permission from the author.
Downloadable versions at http://www.ojai.net/matt/downloads/scriptingTutorial.hqx and http://www.ojai.net/matt/downloads/scriptingTutorial.zip.
Please do not confuse this tutorial with a certain other Frontier 5 tutorial based upon my earlier work.
This page created with Frontier, 2/11/2000; 6:59:05 PM.