A decorator to be used on an object's init method, adding the method "perform_selector" to the object. A method name (message) can then be passed to that method. If the object can handle that message, it does so. Otherwise, it forwards the message to its delegate, where possible.
import types
def handle_selector(f):
"""
Decorator function implementing a chain of responsibility with message sending.
"""
def perform_selector(*args, **kwargs):
self = args[0]
selector = args[1]
if hasattr(self, selector) and callable(getattr(self, selector)):
params = args[2: ]
return getattr(self, selector)(*params, **kwargs)
elif not hasattr(self, 'delegate'):
raise Exception('Selector not handled: %s' % (selector))
else:
params = args[1: ]
return self.delegate.perform_selector(*params, **kwargs)
def wrapper(*args, **kwargs):
me = args[0]
me.perform_selector = types.MethodType(perform_selector, me)
return f(*args, **kwargs)
return wrapper