[Zope3-dev] what is ZCML?

Jeff Shell eucci.group at gmail.com
Mon Mar 13 16:16:17 EST 2006


On 3/13/06, Alec Mitchell <apm13 at columbia.edu> wrote:
> On Monday 13 March 2006 10:59, Dieter Maurer wrote:
> > Note, that configuration files should be understand and
> > adaptable by administrators. Therefore, they should be readable
> > and understandable -- without an understanding of the implementation
> > (but with reading of the component documentation).
>
> +1 The first time I saw:
>
> <adapter factory=".MyFactory" />
>
> I was a bit disturbed.  What's the point?  It tells you nothing unless you
> refer to the actual implementation.  Why not just put the registration in
> python alongside the implementation if that's where the configuration of
> provided and required interfaces is going to be?  I had considered one of
> zcml configuration's greatest benefits was that it could give a high level
> overview of how pieces of a package were interconnected.  Of course it's
> still possbile to do things the old way, but I get the impression that it's
> discouraged.  Brevity is not always a boon, though that cuts both ways here
> (adding a new "magical" seeming zcml declaration to save a copy/paste here
> and there may not be the best idea either).

I consider one of ZCML configurations greatest detriments is that it
does many things that cannot be easily replicated in Python (one day,
you'll probably come across having to set up just the right unit test
harness and you'll realize what I mean).

I consider one of it's greatest detriments is that it completely
destroys Don't-Repeat-Yourself. You can do:

<adapter factory=".MyFrank"
    provides=".interfaces.IFrank"
    for=".interfaces.IBun .interfaces.IRelish"
    />

class MyFrank(object):
    def __init__(self, context):
        # ...

See? No declarations on MyFrank that says what it does. Or you can do:

class MyFrank(object):
    implements(IFrank)
    adapts(IBun, IRelish)

    def __init__(self, context):
        # ...

And do the full <adapter> line in ZCML. But then you've just said the
implements / adapts twice. Using different words, I should point out.
Or you can do the <adapter> line the short way and let the Python code
say what it does.

Three options. I know I'm not consistent with the ones that I choose.
I just know that I spend more time looking at Python code and I'd
rather understand what the Python code is doing by looking at the
Python code.

Three options. That sure kills the "there should be one, and only one,
obvious way to do it" theory too. Don't even get me started about when
I might want to use 'zope:view', 'browser:view', or just plain old
'adapter' (since a view is just a multi adapter, as are content
providers and viewlets and all sorts of other fun and useful
combinations).

Anyways - for me, the point of <adapter factory=".MyFactory"> is that
I already said in MyFactory that it implements and adapts certain
interfaces already. I don't want to say that twice. And I think it's
very important for the Python code to say what it does, so when I come
back to a module five months later I'm not staring at MyFactory going
"yeah, but what is it?"

And I also think it's important for code to be debuggable,
inspectable, so that when there's a bug from ... well, wherever it
came from, code can be traced. It's very hard to trace through ZCML
statements, and what they've produced. From dynamically made classes
to the weirdness of the metaconfigure.py code (handlers,
discriminators, etc) - all of those things get in the way of a
productive pdb or "why is this thing blowing up?" session real fast.
In my experience anyways. So I figure - the less ZCML I use, the
better it will be for me to maintain in the future.

--
Jeff Shell


More information about the Zope3-dev mailing list