Sometimes, more than one method of a PyProtocols generic function (or entry in a Dispatcher
object) applies in a given circumstance. For example, you might need to sum the results of a series of pricing rules in order to compute a product’s price. Or, sometimes you’d like a method to be able to modify the result of a less-specific method.
For these scenarios, you will want to use one of several “result combination” techniques, ranging from using a provided subclass of GenericFunction
or Dispatcher
, to rolling your own entirely custom combination approach.
See the full article at Generic Function Result Combination in the PEAK DevCenter Wiki.
(P.S. for Lispers: the article also documents PyProtocols’ CLOS-style method combining, including “call next method” and “before/after/around” methods, and shows you how to create custom qualifiers as in CLOS. However, unlike CLOS, PyProtocols uses unambiguous logical implication for ordering rather than CLOS’s lexical ordering and asymmetric argument dispatch techniques. That is, in the presence of ambiguity, it forces the programmer to say what they mean instead of using semi-arbitrary precedence rules.)
I used something like this for a project awhile back. Messages could be ‘classified’ by user-defined predicates (implemented with generic functions). Since I wanted multiple classifiers to match, I needed to combine the matching functions, something like this:
def classifier_combiner(funcs):
….def combined_classifiers(message):
……..classifiers = [
…………classifier for classifier in
…………[f(message) for s,f in funcs]
…………if classifier is not None
…………]
……..message.addClassifiers(classifiers)
….return combined_classifiers
The API might have changed since I wrote that function, but the ability to combine methods allows you to do some powerful stuff. I’m currently reading The Art of the Metaobject Protocol, which walks through the design of CLOS. It’s given me a greater appreciation of peak.dispatch’s simplicity (it’s a good book too.. if you haven’t read it, you’re missing out..)
CL is a thorn in my side screaming “learn me if for no other reason then to be able to intelligently choose to not use me”