I'm currently experimenting with the ZCA and I've run into a bit of a hitch. The script below defines an IFuncttion interface, which is used to create function objects that can be chained (i.e. monads).
In this example, I'm trying to create a simple writer monad as an adapter, but getMultiAdapter is raising a ComponentLookupError. Why is this?
from zope import component, interface
class IFunction(interface.Interface):
name = interface.Attribute('Name of the function object')
def __call__(*args, **kw):
"""Call the function"""
class Function(object):
name = ''
interface.implements(IFunction)
def __call__(self, *args, **kw):
return self.run(*args, **kw)
def run(self, *args, **kw):
raise NotImplementedError
class MWriter(object):
component.adapts(IFunction, IFunction)
interface.implements(IFunction)
def __init__(self, prv, nxt):
self.prev, self.next = prv, nxt
def bind(self, x, log=None):
log = log or []
result, line = self.prev(x)
log.append(line)
return self.next(result, log)
def __call__(self, *args, **kw):
return self.bind(*args, **kw)
class AddOne(Function):
name = 'addone'
def run(self, x):
return x + 1
class MulTwo(Function):
name = 'multwo'
def run(self, x):
return x * 2
component.provideAdapter(MWriter)
print component.getMultiAdapter((AddOne(), MulTwo()), MWriter)(11, [])
You should not pass in the adapter you want to look up to
component.getMultiAdapter(). The second argument to that function is the name used for named adapters, but your registration did not use a name.Simply remove that second argument:
Unfortunately, calling
MWriter()still fails because you expectself.prev()to return a tuple:but
AddOne()returns just the one integer:so you get an exception:
Perhaps you wanted each
Function()to return the name as well as the result:but then calling
self.next()fails because it doesn't accept the extralogargument passed in.