• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Please Pass the Handler
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Please Pass the Handler


  • Subject: Please Pass the Handler
  • From: Arthur J Knapp <email@hidden>
  • Date: Fri, 11 Jan 2002 16:40:57 -0500

In some programming languages, you can pass a handler, (function or
subroutine), to another handler, so that the passed handler can
provide custom functionality. A typical example would be JavaScript's
sort() method of arrays, where you pass a comparison function that
tells sort() how to compare any two items in the array.

In AppleScript, it has been shown that a handler can be passed
around as a parameter, but that the act of actually calling the
handler is complicated by AS's bizarre variable-scope rules.

The following are techniques that allow handlers-as-parameters,
ending with a new realization that I had today:


This is how NOT to pass a handler as a parameter:

on PassThisHandler()
return "Successful !!!"
end PassThisHandler

on CallTheHandler( handlerParameter )

return handlerParameter()

end CallTheHandler

CallTheHandler( PassThisHandler )
--
--> error "<<script>> doesn't understand the handlerParameter message."


As you can see, the calling handler can't treat one of it's paramters
as a handler.

One way to deal with the scope problem is to have the calling handler
set it's parameter to a top-level property:

on PassThisHandler()
return "Successful !!!"
end PassThisHandler

property gHoldTheHandler : missing value

on CallTheHandler( handlerParameter )

set gHoldTheHandler to handlerParameter -- Set

set returnValue to gHoldTheHandler()

set gHoldTheHandler to missing value -- Restore

return returnValue

end CallTheHandler

CallTheHandler( PassThisHandler ) --> "Successful !!!"

This seems to work because, (I guess), properties and handlers share
the same scoping rules in AppleScript. The major problem with the
above technique is the set/restore procedure. I suppose you don't
*have* to clear the passed-handler from the property, but it seems
like good coding practice to do so.

A different way to go about this is to give up passing handlers
around, and to simply pass script objects around, containing the
handler you want to use:

script HoldTheHandler

on PassThisHandler()
return "Successful !!!"
end PassThisHandler

end script

on CallTheHandler( scriptParameter )

return PassThisHandler() of scriptParameter

end CallTheHandler

CallTheHandler( HoldTheHandler ) --> "Successful !!!"

Right away, you'll notice the problem that this technique
requires the calling handler to know the name of the handler
in the script object, which makes this system less flexable.


One way to avoid using a top-level script object, and to get
away from the calling handler having to know the name of the
passed-handler, is to simply have the calling handler create
it's own script object:

on PassThisHandler()
return "Successful !!!"
end PassThisHandler

on CallTheHandler( handlerParameter )

script HoldAHandler
property theHandler : handlerParameter
end script

return theHandler() of HoldAHandler

end CallTheHandler

CallTheHandler( PassThisHandler ) --> "Successful !!!"

I think I like this method the best, as it allows the calling
handler to define it's own names for things, ie: it doesn't
have to know that the handler's defined-name is PassThisHandler.


In any case, I just realized today that there is yet one more
trick that can be used:

on PassThisHandler()
return "Successful !!!"
end PassThisHandler

on CallTheHandler( scriptParameter )

return PassThisHandler() of scriptParameter

end CallTheHandler

CallTheHandler( me ) --> "Successful !!!"

Notice, we've gone back to passing a script object, but we
don't have to create a script object, because *me* is a
script object, refering to your entire script!!!

Now, on the face of it, this might seem silly. If the calling
handler knows the name of the passed-handler, why doesn't it
just call it directly:

on PassThisHandler()
return "Successful !!!"
end PassThisHandler

on CallTheHandler()

return PassThisHandler()

At least one good reason would be when working with script
libraries, ie: you've loaded a compiled script via the
"load script" command. These loaded scripts, unfortunately,
do not have access to your script's top-level namespace. By
passing "me" as a parameter, you've given the loaded script
complete access:

-- compiled script file "ScriptLib"
--
on DoSomthing( scriptParameter )
-- stuff
GetValue() of scriptParameter
-- more stuff
end DoSomthing


-- your script
--
on GetValue()
return -- something
end GetValue

set ScriptLib to load script "MacHD:ScriptLib"

DoSomthing( me ) of ScriptLib


Of course, we've gone back to having to know the actual
defined-name of the handler, but it's another tool for
our scripting tool belt. :)


P.S. If I've confused everybody, I'm sorry. Scott Norton will
no doubt set things straight once he reads this. :)



{ Arthur J. Knapp, of <http://www.STELLARViSIONs.com>
<mailto:email@hidden>
(*) Happy
( ) Sad
( ) Ambivalent
( ) Ubiquitous
}


  • Follow-Ups:
    • Re: Please Pass the Handler
      • From: email@hidden (Michael Sullivan)
  • Prev by Date: Re: HD name change for X
  • Next by Date: Re: Differentiating between "A1", "A12", "A13"
  • Previous by thread: Re: Problems with Smile 1.8.4 and system 9.2.2
  • Next by thread: Re: Please Pass the Handler
  • Index(es):
    • Date
    • Thread