[Zope3-dev] Re: a plan for widgets?

Tres Seaver tseaver at palladion.com
Tue Mar 21 08:31:50 EST 2006


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Jeff Shell wrote:
> On 3/20/06, Tres Seaver <tseaver at palladion.com> wrote:
> 
>>So *don't use ZCML*;  use Python:  there is literally nothing which can
>>be done in ZCML which cannot be done in Python.  I wish that folks who
>>don't like / need ZCML would quit trying to dictate how the rest of us
>>use ZCML.
> 
> 
> "Literally nothing"? Try literally everything. I'm sorry. But that was
> the experience I had that set me in such a bad temperament. I had no
> idea what half of these directives were doing, and when trying to
> duplicate them in a test environment I nearly threw the laptop to the
> ground and swore of programming forever. I was *INCREDIBLY*
> frustrated. There is a lot of potentially valuable functionality
> *hidden behind ZCML*. If a ZCML directive were a one line
> wrapper/adapter around a common function, I'd feel different.

If a directive is too magical for you, and you don't mind writing
Python, then *don't use it*.  Consider the following:

 <browser:page
    name="myview.html"
    for="ISomeInterface"
    permission="zope.Public"
    template="templates/myview.pt"
   />

If you consider what it does (register a view which uses a
filesystem-based template) rather than how it does it (i.e., synthesize
a new class for use as a view factory and bind a template to it).  If
you don't like the implementation, and don't mind the boilerplate, then
why not write:

  class MyView(object):

    index = zope.pagetemplate.pagetemplatefile.PageTemplateFile(
                                     'templates/myview.pt')

    def __init__(self, context, request):
        self.context, self.request = context, request

    def __call__(self, *args, **kw):
        return self.index(*args, **kw)

   zope.security.checker.defineChecker(MyView,
                    zope.security.checker.CheckerPublic)

   zope.component.provideAdapter(
      (ISomeInterface,
       zope.publisher.interfaces.browser.IBrowserRequest),
      MyView, 'myview.html')


Note that I am *not* arguing in favor if the current implementation of
<browser:view> / <browser:page>;  in fact, I think it is needlessly
complex.  But I am strongly against the idea of tossing the directive on
that account, and thereby breaking deployed applications.

> My argument and wish has been only this: simplify ZCML. Make it more
> transparent what it is doing.

There is a classic tension here between "convenience" and "purity".
Please recall the many of the directives in ZCML were *added* because
people got tired of typing repetitious boilerplate (imagine the Python
code above repeated *dozens* of times in a given application).

>>Or, if you like ZCML but don't like the current directive set, feel free
>>to propose a new set of directives you think are better, and implment
>>them in *your* namespace:  if enough other people like them, we can talk
>>about making people who are already using the current set change.  But
>>let's quit tearing up what people have alredy learned in favor of a
>>it-must-be-better-because-its-new variant which doesn't yet exist, and
>>whose improved usability we have to take on faith.
> 
> 
> My set of directives is <adapter>, <utility>, <class>, and maybe
> <interface>. Inside of <class>, <requires>, <allows>, <implements>,
> and <factory> (because I do believe that 'factory' there is a nice
> shortcut).

So just use those.  But *don't* argue that the rest of us mustn't define
or use more convenient directives.

> Nothing new. Only less. Less concepts to have to remember. Less
> concepts to have to look up. Less code to have to try to follow when
> it's 10:30 at night and I've been working six hours too long and I
> still can't figure out why my field adapter on an IChoice isn't
> getting its value set properly and I can't get a vocabulary
> bootstrapped up to write a test to debug and then verify the fix of
> it.
> 
> Make ZCML do whatever you want. But if you're going to share it, it
> needs a HELLUVA lot better documentation. I'm glad for what's there
> now. But I've been surprised by ZCML one time too many, and have lost
> too many hours trying to figure out the surprise. Too many similar
> directives, too many possible attribute combinations, and too little
> information about what certain choices will actually do or what
> they're good for. And the source is not a readable, reliable backup
> point to look at.
> 
> 
>>I'll note that the "Refactor mercilessly" meme from XP is *not*
>>particularly well-suited to frameworks / libraries:  it is best suited
>>when applied to *applications*, where the impacts of such changes are
>>borne entirely by the people who make them.  When you tear up the API of
>>a framework / library, you force *other* people to make changes, often
>>without any particular benefit to them.
> 
> 
> What is well suited to frameworks and libraries is to provide maximum
> playability with a minimum number of concepts. When the component
> architecture was simplified (Zope 3.0 -> Zope 3.1), the whole thing
> suddenly made a whole lot more sense to me. Utilities and Adapters.
> Nice. There are a lot of ways those can be combined, especially when
> multi-adapters come into play. But the core concepts are clean and
> simple.

The changes you are talking about also require that folks who built
ablications against Zope 3.0 must tear those applications apart before
upgrading to Zope 3.2, because the underlying mechanismes changed.

> Transparency also counts, especially with open source. Even with books
> and APIDOC, I still have to consult the source a lot (and a lot (and a
> lot (and a lot (and a lot)))) to try to understand the best
> application / use of something. ZCML lacks transparency - the language
> of the directive implementation seldom plays out like something I can
> read and understand. There's another framework, another run-time,
> going on there. And I understand why: it's bootleg/startup service.
> But when shit breaks, or acts funny, debugging it is nearly
> impossible. At least with Zope 2's initialize(context), I could stick
> a pdb.set_trace() at the beginning of such a function implementation
> to step through the loading process. It wasn't the easiest code to
> follow, and was a long and painful process sometimes, but I could at
> least follow obscure (and accidental) bugs and problems to the source.
> 
> Go ahead and make ZCML the most beautiful new language you want it to
> be. But it's got *severe* problems right now. And the "just about
> anything doable in ZCML can be done in Python" line does not work. I
> have scars to prove it.

I have similar scars related to the "refactdor mercilessly" meme which
prevails in Zope3.


Tres.
- --
===================================================================
Tres Seaver          +1 202-558-7113          tseaver at palladion.com
Palladion Software   "Excellence by Design"    http://palladion.com
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org

iD8DBQFEIABG+gerLs4ltQ4RAoFrAJ9Yszu1rB8zOLJ6b+h4xWvPb0vXXgCgogFZ
2c0yYcjMzOMuPCg3M4B82Rs=
=jM3d
-----END PGP SIGNATURE-----



More information about the Zope3-dev mailing list