How to use List and Record data types in your UserTalk scripts.
A list is an ordered collection of values of any type, each of which is called an element. A list can contain as many elements as you like, subject to memory constraints. A list can contain other lists.
Lists are most like strings in Frontier, except that instead of containing characters, they can contain any data type. You can even mix types in a single list.
Many Macintosh applications use lists in their Apple Event interfaces, so lists can be a convenient way to pass information around between apps.
How lists work
To create a new list variable, you can assign it a list value, or use Frontier's built-in new verb. In other words,
local (myList)
new (listType, @myList)
is the same as
local (myList)
myList = {}
To create a new list containing three basic colors:
myList = {"red", "green", "blue"}
To find out how many elements are in the list:
sizeOf (myList)
To loop over all the elements in a list:
local (i)
for i = 1 to sizeOf (myList)
msg (myList [i])
The fragment above displays red, then green, then blue, in Frontier's main window. Note the use of indexing. myList [1] is the string "red", myList [2] is "green", and myList [3] is "blue".
Looping over all the elements of a list comes up so often that we added a shorthand for it. You could rewrite the example above as:
local (element)
for element in myList
msg (element)
Deleting list elements
To delete an element from a list, use Frontier's built-in delete verb. For example:
myList = {"red", "green", "blue"}
delete (myList [1])
msg (myList)
displays {"green", "blue"}.
List arithmetic
Addition and subtraction work with lists too. When you add one list to another, the result is the concatenation of the two lists. To test it out, try typing this in the Quick Script window:
{1,2,3} + {2,3,4}
The result is {1, 2, 3, 2, 3, 4}. Note that 2 and 3 appear twice in the result because they appear in both of the lists.
Lists are like strings, except that instead of containing characters, they can contain any data type. List subtraction works just like string subtraction. For example, type this into the Quick Script window:
"New York" - " York"
The result is "New". But if you enter:
"New York" - "kroY "
The result is "New York". Even though all the characters appear in "New York", they aren't in the right order. For string subtraction, therefore, order counts.
Lists are like strings. Try this out in the Quick Script window:
{1,2,3} - {2,3}
The result is 1.
If instead, you type this:
{1,2,3} - {3,2}
the result is {1,2,3} because the pattern {3,2} does not occur in {1,2,3}. Like strings, with lists, order counts.
Storing lists, fancy lists, comparing lists
As with any other type, you can store lists permanently in the object database:
scratchpad.namesList = {"Martha", "Paul", "Susan", "Joe"}
Lists can contain elements with different types:
scratchpad.randomList = {"Martha", 1, "Susan", clock.now ()}
Lists can even contain other lists:
scratchpad.listOfLists = {scratchpad.namesList, scratchpad.randomList}
The result is:
{ {"Martha", "Paul", "Susan", "Joe"}, {"Martha", 1, "Susan", "11/8/93; 10:36:44 AM"}}
This is different from:
scratchpad.namesList + scratchpad.randomList
which results in:
{"Martha", "Paul", "Susan", "Joe", "Martha", 1, "Susan", "11/8/93; 10:36:44 AM"}.
The first version is a list containing two lists. The second is a list containing six values.
You can test two lists for equality. Order counts. For example, the following one-liners are all true:
{1,2,3} equals {1,2,3}
{1,2,3} equals {1,2,1+1+1}
{1,2,3} equals ({1,2} + {3})
But these are false:
{1,2,3} equals {3,2,1}
"abc" equals "cba"
Remember, lists are like strings.
As with strings, you can use the beginsWith, contains and endsWith operators on lists. The following expressions are all true:
{1,2,3} beginsWith {1,2}
{1,2,3} beginsWith 1
{1,2,3} contains 1
{1,2,3} contains {2,3}
{1,2,3} endsWith 3
{1,2,3} endsWith {2,3}
All comparisons are case-sensitive when applied to string elements. So the following one-liner is false:
{"Maine", "Idaho", "Georgia"} contains "IDAHO"
putAppleListItem & getAppleListItem
In previous versions of Frontier, it was possible to create lists and query them using the built-in verbs putAppleListItem and getAppleListItem. They are still supported in Frontier 3.0, so if you have scripts that use these verbs, you're in good shape. But the new syntax for lists is much more convenient and sensible for scripts that run in Frontier 3.0 and beyond.
Records -- another new data type!
Records are another new data type. Records are a lot like lists, the main difference is that each element of a record has a 4-character name. This effects how records are created, added and subtracted.
Here's what a record looks like:
{'name': "Bill Clinton", 'org ': "United States of America", 'age ':46}
There are no rules about the types of the element. In one record, the element named 'age ' could be a string value, in another record it could be a number.
Many applications use records in their Apple Event interfaces, so records can be convenient for passing information around between apps.
Even though one of the sample scripts for records implements a small record-oriented database in a Frontier table, we recommend using a real database to store field-and-record oriented information. Think of records as a convenient way to pass structured information between applications.
How records work
The simplest way to create a new empty record is to use Frontier's built-in new verb:
local (myRec)
new (recordType, @myRec)
If you want to create a new record that's not empty, you can use assignment. For example, the following script creates a new record called myRec that contains three fields, one for a person's name, organization and age:
local (myRec)
myRec = {'name': "Bull Mancuso", 'org ': "Mancuso Investigations", 'age ':38}
Even though an element name may have one, two or three "real" characters, you still have to include blank characters to make it exactly four characters long.
To find out how many elements are in the record:
sizeOf (myRec)
To loop over all the elements in a record:
local (i)
for i = 1 to sizeOf (myRec)
msg (myRec [i])
The script above displays Bull Mancuso, then Mancuso Investigations, then 38.
The for..in loop structure that we introduced for lists also works for records:
local (element)
for element in myRec
msg (element)
Adding an element to a record
You can easily add an element to a record by assigning to the element.
Consider this script:
local (myRec)
myRec = {'name': "Bull Mancuso", 'org ': "Mancuso Investigations", 'age ':38}
myRec ['home'] = "Upstate, NY" «add a field named home
When this script is complete, myRec has four elements.
Deleting record elements
To delete an element from a record, use Frontier's built-in delete verb. For example:
local (myRec)
myRec = {'name': "Bull Mancuso", 'org ': "Mancuso Investigations", 'age ':38}
delete (myRec [1])
msg (myRec)
displays {'org ':"Mancuso Investigations", 'age ':38}.
You can also specify which element to delete by providing the name of the field to delete:
delete (myRec ['age ']) «delete the field named 'age '
msg (myRec)
which results in {'org ':"Mancuso Investigations"}.
Is an element there?
You can use Frontier's built-in defined verb to determine if a record contains a specific element. For example:
myRec = {'name': "Bull Mancuso", 'org ': "Mancuso Investigations", 'age ':38}
if defined (myRec ['abcd'])
dialog.alert ("You'll never see this message!")
You'll never see the dialog since myRec does not contain an element named 'abcd'.
You can get the name of any element using the nameOf verb:
msg (nameOf (myRec [2])) «displays 'org '
Storing records, fancy records, comparing records
As with any other type, you can store records permanently in the object database:
scratchpad.personRec = {'name': "Bull Mancuso", 'org ': "Mancuso Investigations", 'age ':38}
You can test two records for equality. Unlike lists, the order of fields doesn't make a difference. For example, the following one-liners are both true:
{'fnam':"Bill", 'lnam':"Clinton"} equals {'lnam':"Clinton", 'fnam':"Bill"}
{'fnam':"Bill", 'lnam':"Clinton"} equals {'fnam':"Bill", 'lnam':"Clinton"}
You can use the beginsWith, contains and endsWith operators on records. For example, the following are all true:
{'fnam':"Bill", 'lnam':"Clinton"} beginsWith {'fnam':"Bill"}
{'fnam':"Bill", 'lnam':"Clinton"} contains {'fnam':"Bill"}
{'fnam':"Bill", 'lnam':"Clinton"} endsWith {'lnam':"Clinton"}
As with lists, these comparisons are case-sensitive. So the following one-liner is false:
{'fnam':"Bill", 'lnam':"Clinton"} beginsWith {'fnam':"BILL"}
Record arithmetic
If lists work like strings when you add and subtract them then records work like nothing you've ever seen. You may occasionally use record arithmetic, but the same effect can usually be accomplished with assignment and Frontier's delete verb, and often it's more straightforward.
Here are a few one-liners that show how record addition and subtraction work:
scratchpad.rec1 = {'name':"Florida", 'abbr':"FL", 'capi':"Tallahassee"}
{'name':"Florida", 'abbr':"FL", 'capi':"Tallahassee"}
scratchpad.rec1 = scratchpad.rec1 + {'year':1845}
{'name':"Florida", 'abbr':"FL", 'capi':"Tallahassee", 'year':1845}
scratchpad.rec1 = scratchpad.rec1 - {'year':1845}
{'name':"Florida", 'abbr':"FL", 'capi':"Tallahassee"}
scratchpad.rec1 = scratchpad.rec1 - {'capi':"Dover"}
{'name':"Florida", 'abbr':"FL", 'capi':"Tallahassee"}
General rules for lists and records
Following are some general rules governing the behavior of lists and records in Frontier:
- When adding two records together, any item in the second record whose key already appears in the first record is ignored.
- When subtracting records, the elements must match both in name and value.
- Any list or record can be coerced to a string, or to a binary value.
- Any scalar value coerces to a single-item list, except for records and binary types.
- A single-item list can be coerced to any type to which that item can be coerced.
- Only object specifiers, binary values, or empty lists can be coerced to a record.
© Copyright 1996-97 UserLand Software. This page was last built on 5/7/97; 1:39:36 PM.
It was originally posted on 5/6/96; 9:11:47 PM.
Internet service provided by Conxion.