Online Book Reader

Home Category

AppleScript_ The Definitive Guide - Matt Neuburg [86]

By Root 1374 0
approach (which I owe to Michael Terry) is to take advantage of script object inheritance (Chapter 8) and the continue command, which can pass parameters to any event:

property args : null

script s

on run {what, what2}

display dialog what & space & what2

end run

end script

script trampoline

property parent : s

continue run args

end script

set args to {"howdy", "there"}

run trampoline

If you give your script as a whole an explicit run handler that expects parameters, you won't be able to run your script in the Script Editor or in most script runners. For example:

on run {what}

display dialog what

end run

That's an unrunnable script, unless you have some way to supply the parameter. One approach is to save the script as a compiled script file and then use run script to run the file along with a parameter.

Clearly a run handler with parameters is an oddity, but there are circumstances where it is useful. For example, an Automator action's script has a run handler that takes parameters (see Chapter 27).

Recursion


A handler is visible from within itself. This means that recursion is possible; a handler may call itself.

Explaining the elegances and dangers of recursion is beyond the scope of this book. The best way to learn about recursion is through a language like Scheme or LISP , where recursion is the primary form of looping. In fact, in conjunction with lists, AppleScript's recursion allows some remarkably Scheme-like (or LISP-like) modes of expression (see "LISP-likeness " in Chapter 4).

Tip

The best way to learn Scheme is to read Harold Abelson et al., Structure and Interpretation of Computer Programs, 2nd Edition (MIT Press, 1996), the best computer book ever written.

For example, here's a recursive routine for filtering a list. We'll remove from the list everything that isn't a number:

on filter(L)

if L = {} then return L

if {class of item 1 of L} is in {real, integer, number} then

return {item 1 of L} & filter(rest of L)

else

return filter(rest of L)

end if

end filter

filter({"hey", 1, "ho", 2, 3}) -- {1, 2, 3}

AppleScript is not a truly recursive language, however; recursion is limited by the depth of AppleScript's internal stack. If you recurse too deep (which usually means recursing through too long a list), you'll get a "stack overflow " error message. Unfortunately there's no way to know in advance what the limit is, as it depends on what happens during each recursion and on what environment is running the script. Just to give a typical example, using Script Editor on my machine, this code runs fine if max is 504 but fails with a stack overflow if max is 505; but in Smile it works even if max is as large as 8159:

on remvix(L, ix)

if L is {} then return {}

if ix is 1 then

return rest of L

else

return item 1 of L & remvix(rest of L, ix - 1)

end if

end remvix

set L to {}

set max to 505

repeat with x from 1 to max

set end of L to x

end repeat

remvix(L, max)

Be careful when assigning a recursive handler as a value to a variable. At the point where the handler calls itself, its name is hard-coded into its functionality. After assigning the handler functionality to a different variable name, that name may no longer be in scope and the handler will break when called under its new name:

script s

on filter(L)

if L = {} then return L

if {class of item 1 of L} is in {real, integer, number} then

return {item 1 of L} & filter(rest of L)

else

return filter(rest of L)

end if

end filter

end script

set f to s's filter

f({"hey", 1, "ho", 2, 3}) -- error: «script» doesn't understand the filter message

Power Handler Tricks


A handler takes values as parameters and returns a value. A handler is a value. A script object is a value and can contain a handler. If these facts suggest to your mind an intimation of amazing possibilities, read on.

Handler and Script Object as Parameter


You can pass a handler as a parameter to handler. The difficulty is in calling it. This code fails with a runtime error:

on sayHowdy( )

display dialog "Howdy"

end sayHowdy

Return Main Page Previous Page Next Page

®Online Book Reader