Hi Chris, Chris McDonough wrote:
Martin Aspeli wrote:
We need to make sure that we're not inventing a different way to achieve something which is already possible. This will lead to confusion, because people will have to know "which way" is applicable in a given situation, and the distinction will seem arbitrary.
I fear we are indeed inventing a different way to achieve something which is already possible. We aren't doing it arbitrarily, though: the current way just requires the use of an interface instead of a string. Interface usage for such a simple pattern implies a cognitive load that appears to exceed the pain point of most Python developers who are not already familiar with Zope. So we'd like to ameliorate that as best we can.
I wish I knew what "ameliorate" meant, but I'm sure I agree. My concern is that we also have a pretty large existing user base to worry about, and we wouldn't want to confuse them. Or, indeed, new users confronted with code that has been written up to this point.
In a system like this, there are no interfaces; the string 'root_factory' performs the same job as the IRootFactory interface for registration and lookup. I'd like to make the ZCA registry operate like this. There's really no reason for there to be an interface hanging around to represent this thing: we're using the ZCA as a complicated dictionary here. I think there is a reason, though you may not agree it's a good one. The interface makes a promise about what the component is supposed to be able to do. We don't enforce that in our duck-typing programming language, but I think there is value in being able to say, "I want an object that conforms to this interface (i.e. delivers what the interface promises) - please get me the best one you've got".
That is indeed the promise. But obviously the object you get back needn't *actually* implement the interface you asked for; it's only conventional. It is the same with a dictionary lookup: if you document that, for your application, reg['root_factory'] will return an object implementing IRootFactory, it's pretty much equivalent as far as I can tell. Use of the ZCA API to store and retrieve instances implementing an interface isn't required to get benefit out of the existence of that interface.
No, that's true, except perhaps that it's two things to worry about: an interface and the related name.
I guess I can only point at the rationales in <http://docs.repoze.org/bfg/1.1/designdefense.html#bfg-uses-the-zope-component-architecture-zca>
Yep, and I agree with these.
Off the top of my head, another way to think of this *might* be to say that the 'dict access' is basically looking up a *named* utility providing a very generic marker interface, e.g. zope.component.interfaces.IUtility or even just zope.interface.Interface. That way reg['foo'] == getUtility(IUtility, name='foo'). Obviously, assignment would register in the same way.
I'm not sure it's "better", though. :)
That would also be fine, and it would normalize things a bit, although the implementation would be harder and it would result in slower lookups. But if it made folks feel better than inheriting from dict, I'd be +1 on it.
I think it would be nicer, because we could tell a story like this: - if you just want a place to store things by name... - ... which can be overridden at runtime or customised with local components ... - ... and you don't care too much about the notion of an interface ... - ... then here's the ZCA way to look up a component by name only To register: reg = getSiteManager() reg['rootfactory'] = MyRoot() To retrieve: reg['rootfactory'] To delete: del reg['rootfactory'] The equivalent ideas would be: reg.registerUtility(MyRoot(), provides=Interface, name='rootfactory') getUtility(Interface, name='rootfactory') reg.unregisterUtility(provides=Interface, name='rootfactory') Although I suspect we want a marker interface that's a bit more specific than just 'Interface' since we already have some things that register interfaces as utility, I think. So maybe: class IAnonymousUtility(Interface): pass Martin -- Author of `Professional Plone Development`, a book for developers who want to work with Plone. See http://martinaspeli.net/plone-book