Miles semanticist at
Sun Jul 20 09:18:55 CEST 2008

On Sun, Jul 20, 2008 at 1:01 AM, Marc 'BlackJack' Rintsch
<bj_666 at> 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
    # 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
            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')



More information about the Python-list mailing list