The FooDoo Lounge

Using Libraries

Index

  1. What is a library?
  2. Why use them?
  3. How to load a library
  4. Library Architecture

What is a library?

One way to think of libraries is that they are a convenient way to re-use code written for one project, in one or more others. One of the many reasons I use them is that they encourage me to generalise - to reduce or eliminate details (which are forever changing) from the code.

Say I want to read a file, process the contents in some way and then write it back out to another file. I could put all this code in one handler, but the next time I want to read a file, I have to either copy & paste some of the code, or write it again. To get around this, I would write generic file read and write routines and one or more text parsing handlers to process the data. These could get 'wrapped' into another handler which just calls the others.

Why use them?

Most people who get into writing scripts tend to find themselves doing similar things in different projects. I used to have a library of sorts out of which I would copy sub routines, but this means that there is a copy, or even worse, a slightly modified copy, of the same thing in each script. When (and it is 'when', rather than 'if') you need to change that routine, you have to change every copy. This can get really ugly when you have a lot of scripts. It may not be a big problem for perl heads dealing with text files, but compiled scripts can't readily be parsed this way and it's still just a solution to a problem that can actually be avoided.

How to load a library

AS offers a few ways of doing this and they make use of a compiled script or script application containing (hopefully) tried & tested sub routine handlers, and this command in the script that is going to use them:

set myCoolLib to load script file "Path:To:Compiled:Script"

Runtime loading

Loading the lib can be done every time the script runs by just declaring it within the main execution handler (run or open) of the script. If you do it this way you probably should consider zeroing it out at the end as shown, to avoid storing a copy each time:

on run
    set myCoolLib to load script file "Path:To:Compiled:Script"

    -- do your stuff

    set myCoolLib to ""
end run

Compile time loading

Libraries can also be loaded at compile time, using the following syntax:

property myCoolLib : load script file "Path:To:Compiled:Script"

This means that the calling script loads a copy of the library every time it is recompiled, (the "Check Syntax" button is clicked in Script Editor) rather than every time it is run. This may or may not suit you.

In either case, the library's handlers are called using tell statements:

tell myCoolLib to go under the boardwalk out of the sun

Loading at runtime means that your script always gets the latest version of the routines and should mean that no duplicates are stored. One downside is that it takes time to execute the load script command, particularly if the library is large or the disk slow. This will only be noticeable on scripts that are otherwise very quick to execute and can be minimised by using a run-only copy of the library.

Loading at compile time means that a copy of the library is loaded and stored in the script file itself. This returns us to a kind of 'multiple copies' situation in that a copy of the library is stored in every script that uses it this way. I actually find this useful in that I get to choose when my scripts load a new version of a lib, i.e. when I'm working on them, as opposed to when I'm trying to use them. This is not why I use the method though.

Using the parent property

One feature available when loading at compile time is that the library can be declared as the parent to the calling script:

property parent : load script file "Path:To:Compiled:Script"

This construct makes the library's handlers available essentially as if they were written into the script. Depending on your viewpoint, this is can be a Bad Thing or a Good Thing. The downside is that every property and handler name is global to the calling script - everything is operating in the same space. This can get very messy in larger projects. The choice should be carefully thought out in these situations, but it does offer some great advantages for lazy people like me.

Libraries loaded in this manner do not require tell blocks. This not only cuts down on typing, but also removes a layer of complexity when using nested tell statements elsewhere in the code. I think of libraries as groups of services. When I start a new project, I add just one line to the beginning - the parent declaration - and instantly have all my oft used facilities available.

Library Architecture

I tend to write libraries containing 'building block' routines - small, simple and highly generalised - which can be called externally, but also contain more complex functions that are built on the others. I try to fulfil specialised requirements in scripts by combining existing handlers in wrappers rather than writing new ones.

Whilst it's a somewhat demanding way to code at first, its benefits multiply over time. I spent a lot of time setting these structures up originally, but it means that I can write complex scripts very quickly now. As with the use of libraries generally, it encourages modularity. I believe it also makes things easier to debug and maintain in the long run.

 

The FooDoo Lounge is Copyright © Richard Morton 2002-2005

|| url: http://www.foodoo.sunreal.com.au/info/libraries.html
|| created: 12-Nov-03, 1:06 PM; updated: 12-Nov-03, 1:06 PM
|| size: 19371 bytes