On Sun, Jul 20, 2008 at 1:01 AM, Marc 'BlackJack' Rintsch <[EMAIL PROTECTED]> wrote: > The methods are a problem IMHO. You can't add an own method/function with > the name `fire()` or `toFunction()`. `MethodChain` has to know all > functions/methods in advance. You can add the methods of whole classes at > once and there are over 300 pre-added, this begs for name clashes.
Name clashes aren't an issue, since MethodChain doesn't apply any special meaning to the method names it knows; the limitation is because JavaScript doesn't allow you to modify property lookup behavior. And since we can make the chain object callable, we don't need "fire" or "toFunction" methods. ########### from functools import partial class MethodChain(object): # The implementation of this could be cleaner. I would prefer # chain.foo() to return a new object instead of modifying chain. # But this is easier to write and closer to the JavaScript implementation. def __init__(self): self._methodname = None self._chain = [] def __getattr__(self, methodname): assert self._methodname is None self._methodname = methodname return self def __call__(self, *args, **kwargs): if self._methodname is None: assert len(args) == 1 and not kwargs result = args[0] for method in self._chain: result = getattr(result, method[0])(*method[1], **method[2]) return result else: self._chain.append((self._methodname, args, kwargs)) self._methodname = None return self def compose(*callables): def composition(arg): result = arg for callable in callables: # or should that be reversed(callables)? to be mathematically # accurate, yes, probably; however, it also makes sense to # specify the callables in the order they'll be applied result = callable(result) return result return composition chain = MethodChain().lower().replace('ello,', 'ey').title().split() print chain('HELLO, world') func = compose(chain, partial(map, lambda s: s+'!'), ' '.join) print func('HELLO, world') ########### -Miles -- http://mail.python.org/mailman/listinfo/python-list