Frontier Tips and Tricks
About This Page
This page contains a somewhat disjointed collection of suggestions, tricks, and things to watch out for when doing Frontier programming. Some of the things here seem pretty obvious to me (and presumably other experienced Frontier users), but may not be so obvious to newbies.
Avoid Changing the Word Character
When you change the word character with
string.setWordChar you are making a global change that will affect everything Frontier does. For this reason, it is very important that before changing the word character you store the original value in a variable, and set it back as soon as you’re done.
It’s actually a fairly bad idea to mess with the word character at all, even if you do remember to set it back. Maybe you’ll forget to reset it, or maybe another script that uses it will run while your script has it set to something else. Anything you can do by setting the word character can be done using regex anyway, so you should do it this way.
Comment Your Code
I’m a firm believer in commenting everything. Extensive comments make your code much easier for others to understand, which is important if you’re planning to release it. They also can help you remember how something you wrote two years and haven’t looked at since worked.
My rule of thumb for my own code is that if there’s any ambiguity at all as to what a line of code is doing, or why it’s doing it, I comment the line. Probably around half the lines of code I write are commented as a result.
Deleting Things in
Suppose you want to loop through every item in a table, do something with it, and then delete the item. You might be inclined to use something like
for i = 1 to sizeOf ( theTable ), with the code inside the loop referring to
theTable[i]. However, this would result in some of the table entries being missed.
This problem can occur with lists and strings as well, since you can use an index to get at individual list items or characters in strings. However, I’ll continue using a table as the example. Just keep in mind that this applies to anything that can be accessed using an index.
For example, suppose you have a table with four entries that you loop through using a
for loop like the one above. The first time through,
i is 1, so the first entry in the table is processed and deleted. However, now the remaining table entries have an index one less than they did before – what was item 2 is now item 1, etc. Now, the second time through the loop, i is 2, but the item that used to be entry 2 is now entry 1, so it never gets acted on by the code in the loop.
This problem is easily avoided, though – just start from the bottom of the table instead of the top. Write the loop as
for i = sizeOf ( theTable ) downTo 1. This way, deleting the entry
theTable[i] will have no effect on the index of the remaining entries in the table, and your loop will get a chance to process all of them.
There are lots of changes between Frontier 4.x and 5.x that need to be accounted for. Every time your script does something that’s different between versions, use an
if statement to check the version, like this:
if frontier.version() beginsWith 5.
The disperal of scripts from the toys suite is an obvious source of problems. Another change which is less noticeable is with
target.set. When using this, it’s important to set the target back to whatever it was before when the script exits, but the way to do this has changed. The F5 way is with
oldtarget = target.set ( @newTarget ). The F4 version requires an additional step:
oldtarget = target.get()
target.set ( @newTarget )
Scripts should be released as Frontier 4 object files unless you’re certain that they will only be used by people with Frontier 5. Frontier 5 can handle F4 objects just fine, but going the other way is a significant inconvenience for the Frontier 4 users.
Declare Your Variables
All local variables should always be declared. Any time you want to use a local variable, don’t just rely on Frontier to create it for you, explicitly declare it with
local ( variableName ). This protects you from accidentally trashing some important part of the root by assuming that it’s safe to use a name that’s in the search path, like “system,” without declaring it as a local variable.
Another benefit is readability. Someone else reading your code will have a much easier time understanding it if they don’t have to figure out which variables are in scope in a particular block of code.