Passing an optional handler to a handler

Hello.

This is something I will use in another context, so this only shows the concept.
And I didn’t figure it out by my self, I was in need, if not in dire, and looked it up in Matt Neuburgs “AppleScript The Definitive Guide” I guess this method is also described elsewhere. -It is nice to have when you need it!

The Example:
Say you have a handler that you wan’t to share with others, but you aren’t exactly aware of how the user wants your routine to perform in some part, say the error handler. :slight_smile:

Then you can pass a handler like this, and the handler can also take parameters, You will even be given the return value of the script object through the result.


bigHandler(smallHandler, 5)
bigHandler(missing value, 5)
on bigHandler(theOther, andAParameter)
	script suppliedHandler
		property thehandler : theOther
		property theParaMeter : andAParameter
		thehandler(theParaMeter)
	end script
	if theOther is not missing value then
		run suppliedHandler
		set theRes to the result
		display dialog "And the result was : " & theRes
	else
		display dialog "I miss the other with " & andAParameter
	end if
end bigHandler

on smallHandler(theParaMeter)
	display dialog "I'm the other And the parameter is " & theParaMeter
	return false
end smallHandler

Afterthoughts: While this is the “clean” way to do it, the most flexible way is to use a global with some name
that is unlikely to clash with some variable name the user will create. -AppleScript usually doesn’t contain 100 of thousands of lines of code, where such clashes are much more likely to occur!

Here is an example of the more flexible solution to the same problem by using a global, but now we can actually send with one of the local variables of the bigHandler to the smallHandler.


bigHandler(smallHandler, 5)
bigHandler(missing value, 5)
on bigHandler(theOther, andAParameter)
	global _bighHandlersHandler
	local aLocal
	set aLocal to "5 too!"
	if theOther is not missing value then
		set _bighHandlersHandler to theOther
		_bighHandlersHandler(andAParameter, aLocal)
	else
		display dialog "I miss the other " & aLocal
	end if
end bigHandler

on smallHandler(theParaMeter, otherParameter)
	display dialog "I'm the other And the parameter is " & theParaMeter & " " & otherParameter
end smallHandler

Best Regards

McUsr

Hi, McUsr.

Another clean method, prefered by many, is to encapsulate the different actions as similarly named handlers within script objects:


script defaultStuff
	on doStuff(theParam)
		display dialog "I miss the other with " & theParam
	end doStuff
end script

script otherStuff
	on doStuff(theParam)
		display dialog "I'm the other And the parameter is " & theParam
	end doStuff
end script

on bigHandler(scriptObject, theParam)
	tell scriptObject to doStuff(theParam) -- or: scriptObject's doStuff(theParam)
end bigHandler

bigHandler(otherStuff, 5)
bigHandler(defaultStuff, 5)

Hello Nigel

I’ll vote for yours! Definitively.

The convoluting script object is the best solution, now the enveloped handler can take parameters from everywhere within its scope, without breaking encapsulation.

The first example for my first post uses a property to “hardwire” the parameter to the called function from the parameter list of the calling function.
The second example is a little bit more flexible, but breaks encapsulation.
Your example keeps that flexibility in that you can call the with sent handler from within the handler with any parameter you want, without side-effects. Nice! No wonder why that is the favorite method.

Edit: I still think it might be more convenient if one make a library for other users, to let the users pass their handlers into other handlers in order to make them comfortably use the said solution:
Then they won’t have to adapt to the coding standard of the library, but have the library to a certain extent adapt to their coding. The could for instance send with a common handler for trapping errors as handler, which I maybe stereotypically guess that most users would prefer.

Best Regards

McUsr