Online Book Reader

Home Category

AppleScript_ The Definitive Guide - Matt Neuburg [88]

By Root 1540 0
integer, number})

end isNumber

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

I consider that example to be the height of the AppleScript programmer's art, so perhaps you'd like to pause a moment to admire it.

Handler and Script Object as Result


A handler may be returned as the result of a handler. Because you can't define a handler directly within a handler, you might have to define it as a handler within a script object within the handler; but this is no bother. So, for example:

on makeHandler( )

script x

on greet( )

display dialog "Howdy"

end greet

end script

return x's greet

end makeHandler

set y to makeHandler( )

y( ) -- Howdy

Of itself, however, this device is not terribly useful; in real life, you're more likely to return a script object rather a handler:

on scriptMaker( )

script myScript

property x : "Howdy"

display dialog x

end script

return myScript

end scriptMaker

set s to scriptMaker( )

run s -- Howdy

In the last two lines, we acquire the script object returned by the handler scriptMaker, and run it. Of course, if we didn't want to retain the script object, these two lines could be combined into one:

run scriptMaker( ) -- Howdy

Why might it be useful to return a script object as the result of a handler? Mostly because the handler can customize the script object before returning it. For example, instead of hard-coding the property x that will be displayed, we can pass that value into the handler as a parameter:

on scriptMaker(what)

script myScript

property x : what

display dialog x

end script

return myScript

end scriptMaker

set s to scriptMaker("Hello")

run s -- Hello

The real virtue of this technique emerges when we retain and reuse the resulting script object. To illustrate, here's one more version of the general list-filtering routine we wrote earlier in this chapter. Previously, we passed a handler both a criterion handler and a list, and got back a filtered list. Now we're going to pass just a criterion handler, and get back a script object, which we will retain. Now we've got a script object containing a filter handler that is already customized to filter any list according the criterion we passed in at the outset. In effect, we've built a custom handler! Now we can reuse that handler repeatedly with different lists. We can even create more than one such handler, each customized to be a certain kind of filter. This architecture is elegant and efficient (and LISPy):

on makeFilterer(crit)

script filterer

property criterion : crit

on filter (L)

if L = {} then return L

if criterion(item 1 of L) then

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

else

return filter (rest of L)

end if

end filter

end script

return filterer

end makeFilterer

on isNumber(x)

return ({class of x} is in {real, integer, number})

end isNumber

on isText(x)

return ({class of x} is in {string, text, Unicode text})

end isText

set numbersOnly to makeFilterer(isNumber)

set textOnly to makeFilterer(isText)

tell numbersOnly

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

filter ({"Mannie", 7, "Moe", 8, "Jack", 9}) -- {7, 8, 9}

end tell

tell textOnly

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

filter ({"Mannie", 7, "Moe", 8, "Jack", 9}) -- {"Mannie", "Moe", "Jack"}

end tell

Another use for a script object as a result of a handler is as a constructor . Here we take advantage of the fact that when a handler is called, it initializes any script objects defined within it. So a handler is a way to produce a copy of a script object whose properties are at their initial value.

As an example, consider a script object whose job is to count something. It contains a property c, which maintains the count, and a handler that increments the count. (This approach is using a sledgehammer to kill a fly, but it's a great example, so bear with me.) A handler is used as a constructor to produce an instance of this script object with its property c set to zero. Each time we need to count something new, we call the handler to get a new script object. Then we can repeatedly

Return Main Page Previous Page Next Page

®Online Book Reader