[ create a new paste ] login | about

Link: http://codepad.org/tWsYomoZ    [ raw code | output | fork ]

Python, pasted on Apr 28:
#from multimethod import dispatch
# module inlined here

class MultiMethod(object):
    registry = {}
    def __init__(self, name):
        self.name = name
        self.typemap = {}
    def __call__(self, *args):
        types = tuple(arg.__class__ for arg in args)
        function = self.typemap.get(types)
        if function is None:
            raise TypeError("no match")
        return function(*args)
    def register(self, types, function):
        if types in self.typemap:
            raise TypeError("duplicate registration")
        self.typemap[types] = function


def dispatch(*types):
    def register(function):
        function = getattr(function, "__lastreg__", function)
        name = function.__name__
        mm = MultiMethod.registry.get(name)
        if mm is None:
            mm = MultiMethod.registry[name] = MultiMethod(name)
        mm.register(types, function)
        mm.__lastreg__ = function
        return mm
    return register


def assert_full_type_coverage(multi_func):
    type_names, type_pairs = set(), set()
    for (t1, t2) in MultiMethod.registry[multi_func.name].typemap:
        type_names.add(t1.__name__)
        type_names.add(t2.__name__)
        type_pairs.add((t1.__name__, t2.__name__))
    for n1 in type_names:
        for n2 in type_names:
            if (n1, n2) not in type_pairs:
                assert False, "Missing function: %s(%s, %s)" % (multi_func.name, n1, n2)

#----------------------------------------------

class Wheel(object):
    def __init__(self, name):
        self.name = name

class Engine(object): pass
class Body(object): pass
class Car(object): pass


class CarElementPrint(object): pass
class CarElementDo(object): pass


@dispatch(Wheel, CarElementPrint)
def visit(obj, action):
    print "Visiting", obj.name, "wheel"

@dispatch(Engine, CarElementPrint)
def visit(obj, action):
    print "Visiting engine"

@dispatch(Body, CarElementPrint)
def visit(obj, action):
    print "Visiting thebody"

@dispatch(Car, CarElementPrint)
def visit(obj, action):
    print "Visiting car"


@dispatch(Wheel, CarElementDo)
def visit(obj, action):
    print "Kicking my", obj.name, "wheel"

@dispatch(Engine, CarElementDo)
def visit(obj, action):
    print "Starting my engine"

@dispatch(Body, CarElementDo)
def visit(obj, action):
    print "Moving my thebody"

@dispatch(Car, CarElementDo)
def visit(obj, action):
    print "Starting my car"


elements = [Wheel("front left"),
            Wheel("front right"),
            Wheel("back left"),
            Wheel("back right"),
            Body(),
            Engine(),
            Car()]

for action in [CarElementPrint(), CarElementDo()]:
    for elem in elements:
        visit(elem, action)
    print


Output:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Visiting front left wheel
Visiting front right wheel
Visiting back left wheel
Visiting back right wheel
Visiting thebody
Visiting engine
Visiting car

Kicking my front left wheel
Kicking my front right wheel
Kicking my back left wheel
Kicking my back right wheel
Moving my thebody
Starting my engine
Starting my car



Create a new paste based on this one


Comments: