Thursday, September 22, 2005

Pydispatcher

I thought I'd give a shout-out here to pydispatcher. It was written by a gent named Pat O'Brien, whom I've met and had lunch with, and it's coming in very handy for Vellum. I've refactored Vellum to use it, and it's remarkably simple and robust. Where it comes in handy is building code where lots of things need to know when program state changes, and need to know where those events came from to decide whether to use them.

The essence is:
   def receiver(sender, arg1, arg2):
if sender=='ninja':
print arg1, arg2

def otherReceiver(arg1, arg2):
if arg1=='oNOerror': sys.exit(1)

dispatcher.connect(receiver, "foo")
dispatcher.connect(otherReceiver, "foo")
...
dispatcher.send('foo', sender='ninja', arg1='yaysuccess', arg2='whatever')
dispatcher.send('foo', sender='phb', arg1='oNOerror', arg2=123)

#==> yaysuccess whatever
#==> eek, error

Signals can be any (hashable?) python object, as can senders.

Even if you think this is a bad way to design an app (signals going all over the place, confusing the call stack), you might find it useful if you don't know how to design your app. Do it with the event dispatch mechanism first, then look for all the places where signals are sent, and figure out how to get them upstream in the call stack from the code handling them.