Introduction
Few scripting or programming environments have anything like the Object Database. It stores data permanently, can contain scripts and data, is hierarchic, is easily accessed interactively and thru scripts, can store huge amounts of data, and it's fast.
The object database is at the heart of the Frontier enviroment.
It's a table
The Object Database is a table that can hold many different types of information, including other tables. Here's a picture of the top-level table in Frontier as we ship it:
Object types
The most common and important datatypes are defined on the "Kind" popup menu in the lower left corner of each table window. They are:
Boolean, Character, Number, Float, Date, Direction, String, String4, Enumerator, File Specifier, Alias, Object Specifier, Address, Table, WP-Text, Picture, Outline, Script, MenuBar, List, Record and Binary.
This list is actually incomplete. Frontier can create other types, they are accessible thru the Table menu, which is in Frontier's menu bar when a table window is frontmost.
Organization of the database
The outline at the right shows you the top part of the hierarchy that makes up the Frontier Object Database as delivered by UserLand.
When you use this database, import scripts and other objects into it, and otherwise customize it, this organization changes, of course.
The base table in the Object Database is called root, like the root of an upside-down tree. It contains seven sub-tables. Each of the tables, in turn, has one or more elements, some of which may be tables. This nesting of sub-tables can continue up to 25 levels deep in the database.
In the following sections we highlight the most important places for newcomers. If you want to view any of these tables, choose the Jump command from the Open menu, and enter the address of the table.
scratchpad
This table is intended as a temporary storage area, although like all Frontier table entries, it is saved to disk and remembered from session to session. You'll probably find frequent use for the scratchpad table, particularly during development and testing of reasonably complex Frontier scripts and suites. It's an easy place for scripts to store preferences. We use this location in some of the example scripts in the documentation as well. Another location for temporary data is the system.temp table, described below.
workspace
This table belongs to you. Put your personal scripts and data here. You can build out structures of tables and sub-tables to organize your work, much as you would use the file system to store your programs and data. Many of the examples in this manual build sample scripts in the workspace table.
suites
Suites are collections of related scripts and data, usually attached to one or more private menus. See Suites for details.
user
This top-level table stores information about you, and information for suites and other scripts. It's important that scripts store their data separately. By storing data in sub-tables of the user table, authors can update the scripts and not overwrite your personal data.
user.callbacks
You can customize and extend the Frontier environment by adding scripts to the sub-tables in this table. These scripts are called when certain actions take place -- such as when Frontier starts up or shuts down, when a window is closed or opened, and so on.
system
The system table is one of the most important sub-tables in Frontier. Like the System Folder in the Macintosh Operating System, it's where the Frontier system itself is defined. It has some things your OS might not have, like agents that run continuously in the background and outlines of scripts that appear in the menu bars of applications that support a special protocol.
system.agents
Agent scripts are stored here. You can add your own agents to this table. See the Agents page for more information.
system.extensions
This is where glue scripts that call DLLs and UCMDs are usually stored.
system.menus
Frontier's menus and their supporting scripts are stored in this table.
system.menus.sharedMenus
On the Macintosh, many scriptable applications support menu-sharing. Their custom menus are stored in the system.menus.sharedMenus table. The names correspond to the 4 character application ID (also known as the application's "creator" code).
system.temp
This table is a place for your scripts to store very temporary data. Unlike the scratchpad table, any data stored in this table is deleted between sessions.
system.verbs
All of the verbs in Frontier are defined in system.verbs and its many sub-tables. If you peruse this sub-table, particularly the sub-table called builtins, you may be surprised to find that a great many Frontier verbs are defined in scripts that use other verbs in the language. Whenever you see a reference to the "kernel," you are looking at a direct call to the Frontier program.
system.verbs.traps
This table is central to Frontier's role as a CGI scripting environment running behind web server software on Macintosh systems. It contains scripts that respond to Apple events sent to Frontier.
Each sub-table of system.verbs.traps has a four-character name, corresponding to a class of Apple events. Each sub-item is a script with a four-character name that corresponds to the "id" of the Apple event. The parameters to the script are the parameters to the Apple event, the returned value of the script is the value that Frontier returns to the Apple event caller.
Changes to UserLand-supplied scripts
One word of caution: although sometimes there is no good alternative, we recommend that you do not edit Frontier's built-in verbs, suites, or application "glue" scripts. If you write other scripts that depend on the changes and then we release a new version, you must either make your changes again or stick with the old version and miss out on improvements.
Further, if you want to distribute your scripts, you would force everyone else to make the same changes. Instead of modifying the original, create your own version in a sub-table of the suites table. If you want to distribute your scripts to others, just include these extra scripts.
Information for each object
Every object in the Frontier Object Database, regardless of type, has three pieces of information stored, corresponding to the three columns in the table:
Every object must have a name. You normally use the name of an object to access its contents, although as we will see in the next section you can use its relative position in the table when that information is known and useful. A Frontier object's name must not be longer than 32 characters. While most of the names you'll see in the Object Database are one word, this is not mandatory. Multi-word names are legal. As we'll see in the next section, they add special addressing requirements for scripts but nothing insurmountable.
What is displayed in an object's value column depends on two factors: the kind of data involved and, if it is non-scalar, whether it has been loaded from the disk during the present session. For example, take a look at Figure 6-1, which is part of the root.examples table as it is shipped by UserLand.
Figure 6-1. Partial Listing of examples Table
Notice that the objects called list1 and list2 are outlines and are stored on disk. The object lunchReminder is a word processing text object that is also on disk. But mouseat is a scalar object, a point, and its value is reflected directly in its entry in the table. Similarly, name is a scalar object, a string, so its value is shown in the table. (Note that the item markers for scalar objects are gray.)
Double-click the item marker beside list1 to open it. Now look at its entry in the examples table. It indicates the contents of the outline as far as Frontier knows them at this point, namely that the outline has five lines.
Accessing the object database from scripts
To retrieve or change the contents of the Frontier Object Database you need a means of addressing objects in the database. The basic approach is to specify the full name of the object, with each sub-table of which it is a member appearing in order from the root level down to the object, and each sub-table's name separated from the others by a period. (The "root" prefix is not required.)
When you want the value of an object, just use its name, e.g.
msg (user.prefs.initials)
When a verb or script needs to act on the object itself, rather than just the value of the object, you specify the address by including the "@" character, e.g.
edit (@user.prefs.initials)
When you can use partial object names
Type the following line into the Quick Script window and execute it:
edit (@menus)
How does Frontier know to open the menus table at system.menus?
For the answer, type the following line into the Quick Script window and execute it:
edit (@system.paths)
The result should look something like Figure 6-2. Examine this table and you'll quickly discover that it is a series of pre-defined paths to tables in the Frontier Object Database. Any object whose full name begins with any of these paths will be found if you supply only the remainder of its name (i.e., the part that would be appended to the end of one of these known paths).
Figure 6-2. Table of Pre-Defined Object Database Partial Paths
It is possible that two of these tables will contain an item that has the same name. Frontier searches this table from top to bottom, using the first match that it finds. For example, if there were two objects called menus, one at suites.menus and one at system.menus, the one in the suites table would essentially override the other unless a complete path to the latter was provided.
We recommend that you do not edit this table, ever. You may lose functionality in Frontier if you do. Even if not, if you change the table and your scripts depend on the change, they will be hard to share with others. This table is very central to Frontier's functionality.
Names containing special characters
In the examples table, there are three sample outlines that are used in DocServer. They are called Sample Outline 1, Sample Outline 2, and Sample Outline 3. If you try to type the name of one of these objects into the Quick Script window, an error condition will result.
edit (@examples.Sample Outline 1)
If you click on the "Go To" button in the Error Info, you'll find the cursor flashing after the word "Outline." Frontier sees this text as a script containing three consecutive table identifiers - "Sample", "Outline", and "1" - with no operators between them. This is an illegal script.
To access such objects in Frontier, you must enclose the multi-word name in quotation marks and then you must enclose the entire quoted string in square brackets:
edit (@examples.["sample outline 1"])
This syntax is actually a special case of the use of square brackets to force Frontier to evaluate the expression contained between them and to use the result of that evaluation as an identifier (the name of a single table or cell). This somewhat advanced technique can be used to create generic scripts that would otherwise have to be customized for a particular user or configuration.
For example, if you want a general purpose script that performs some action on any given website table, you need to a way to include the name of the website. Say you've got a local variable, "websiteName," that contains the name of a website. You could open that website for editing like this:
edit (@websites.[websiteName])
Relative addressing
The objects in a Frontier Object Database table can be referenced by their relative positions in the table. This approach permits you to deal with a Frontier table exactly like an array in other programming languages. The first entry in the table can be addressed as:
table.name [1]
All other entries are similarly addressed. The 12th item is addressable as:
table.name [12]
Let's look at an example. Open the Examples table and sort by Kind (click on the "Kind" label at the top of the table so that it is underlined). Open the Quick Script window, type and run the following:
examples [1]
Assuming the first entry in your Examples table is "nextchar" with a value "M," that's what you'll see in the result portion of Quick Script.
The Jump Command
The fastest way to locate an object in Frontier is with the Jump command from the Main Menu, also accessible by control-J (command-J on Macs) from the keyboard.
Control-double-click
If you are looking at some information in a script (or any other object), you can hold down the Control key and double-click on any Frontier term (object database address) and be taken directly to its definition (location) if it can be found. This technique is often the quickest way to navigate from a script to another script it calls.
On Macs, this keystroke is command-double-click.
Find and Replace
Frontier includes built-in find-and-replace capability. You can use this feature to locate any piece of information you want to find in the Object Database -- though it may take some time.
Tip for Mac users working Windows: if you jump to user.prefs.search, and set winStandardFindCommand to false, the Find dialog will work more like the Mac Find command.
Variables and the database
You can create new entries in the Object Database interactively, as described in Chapter 2 or from a script.
From the Quick Script window, you create a new variable in the Object Database simply by assigning it a value. For example, scratchpad.y does not exist when you installed Frontier. But if you type this line into the Quick Script window, you can then examine the scratchpad table and confirm that it now has an entry called y with a value of 13.04 and a type of double (floating point):
scratchpad.y = 13.04
Objects that have their own editing window can be created with the "new" verb, e.g.
new (outlineType, @scratchpad.partyList)
Local variables
When you create local variables in your scripts, the variables only last as long as the script is running, they are not stored as a permanent part of the Object Database.
As noted in Chapter 3, Frontier creates a temporary series of tables representing a dynamic "stack" while the script is running.
When you are debugging a script, this location is accessible through the Object Database structure at location system.compiler.stack.
Exporting Objects
You can export any Frontier object to the desktop for import to another copy of Frontier or back into your original Frontier root file.
You can also copy Frontier objects and paste them into other applications via the Clipboard, just as you are used to doing with other applications. You can select text from a word processing text object, and paste it into a document in another application. You can do the same with individual headings of Frontier outline objects, with scalars, and with individual names of table entries.
Importing Objects
You can import Frontier objects into any Frontier.root file. If the object was exported from Frontier to a file using the Export command from the Main menu, you can import it into a Frontier.root file one of two ways: by double-clicking on the file, with or without Frontier running (Frontier will be launched if it is not running); or from within Frontier, choosing Open... from the File menu and then choosing the file.
If the object you wish to import into Frontier is a desktop script, you can hold down the control key (command key on Macs) when you double-click its icon and continue to hold the control key down until the script's editing window opens in Frontier.
Using the Clipboard, you can bring text information from other applications into Frontier. Select some text in an application window, copy it, then switch to Frontier. Paste the text.
Personal use of the database
Aside from its value and importance in scripting, the Frontier Object Database is a powerful storage system in its own right. Because it can search in the text of any item, it may be convenient storing notes to yourself, electronic mail messages, organized outlines of electronic mail accounts, records of users on a local area network, outlines of projects, reminders about appointments, and a host of other items that may or may not be related to a script.
Feel free to make extensive use of the database for such things. We recommend that you use your Workspace table as the storage starting point. You can build sub-tables, word processing text entries, and a host of other database entities in this table.
This site scripted by Frontier.