Re: [Zopexmlmethods-devel] Interface for XPathMethod?
Brought to you by:
arielpartners,
philikon
From: Philipp v. W. <ph...@we...> - 2003-06-11 15:22:18
|
Craeg, > I have refactored ProcessorChooser heavily and renamed > it to ProcessorRegistry. However, I am unable to > make it a mirror image of GeneratorRegistry. The > reason is that it does lazy loading. Worse, even. > It can *never* hold an instance of a processor, > because then it would make ZSyncing across > processors impossible. So making Processors register > themselves once at runtime won't work. Okay, that makes sense. There must be some otherway to actually hold the classes. Either the ProcessorRegistry must be hold lazyly oder the classes. Maybe a special __reduce__ method which would not include those processor classes would solve the problem (I really think so!) > So my refactorings don't end up changing much. Basically > I cleaned up the interface and made it more orthogonal, > and changed to using compile() and exec() to eliminate > the explicit calls to specific processors. In the > end, however, I wonder if its really more readable > or maintainable. You're right, you haven't changed much in the end (it looks different, but works the same way). Here's a use-case for the ProcessorRegistry I have in mind: Somebody writes a new XSLT processor and a class that implements our IXSLTProcessor interface in his own party. He would now like to use this processor in XSLTMethod. Here is now I would like to see this: from Products.ZopeXMLMethods.interfaces import IXSLTProcessor class CustomProcessor: __implements__ = IXSLTProcessor ... # processorRegistry is a singleton instance of ProcessorRegistry from Products.ZopeXMLMethods.ProcessorRegistry import processorRegistry # register sees what interfaces CustomProcessor implements and figures # out the rest processorRegistry.register(CustomProcessor) > def prefer(self, processorType, processorName, exclusive=0): > """ > For a given processor type, indicate a preference for one > processor over another. Set the 'exclusive' flag to indicate > that no other choices should be offered, even if available. > To change your preference, simply call this method again. > > Note: if the chosen processor is not available, this advice is > simply ignored. Why? Imagine the case where you make a > choice, then ZSync the object tree to another Zope instance in > which this processor is not available! We must recover > gracefully from this (rather likely) scenario. > """ > self._preferred[processorType.__name__] = (processorName,exclusive) I don't like this __name__ business. Why not deal with the interface directly? Interfaces provide much nicer ways to determine whether a class is "of a certain type" (i.e. whether a class implements that interface). Also, this approach is more Component Architecture-like, thus making it easier to port it to Zope3 eventually. > def InstantiateProcessor(processorClassName, processorName): > """ > > Instantiate a processor of the type whose class name is passed > in and return it. > > Log an error to stdout (the zope log) in case of an Exception, > and return None > > """ > > try: > importStatement = "from %s import %s" % ( processorClassName, > processorClassName ) > code = compile(importStatement, 'Processors.py', 'exec') > exec(code) > clazz = eval(processorClassName) > proc = apply(clazz, ()) > return proc This can be done in a more elegant way: try: klass = __import__(processorClassName, globals(), locals(), [processorClassName]) proc = klass() return proc except: ... Although I still think that it should be possible to register classes instead of names. This way we don't have to rely on some special naming (and placing) convention for processor classes (see the above use case). Phil |