
On Sat, 12 May 2001, Glyph Lefkowitz <glyph@twistedmatrix.com> wrote:
IMHO, people *should* inherit from it, so that we can have some visibility on what implements it. I agree that it should provide as little functionality as possible, however.
No, people should put it in the __implements__ attribute.
In my humble (but correct) opinion, it is *always* bad API design to force the caller to "promise" something. (Sometimes, other design concerns mitigate this decision, but I don't see one here. However, I have frequently joked about having a neon sign in my office, for design discussions, that says "IT IS NOT THE CALLER'S RESPONSIBILITY" in 10-foot-tall letters)
I would much rather see a .getParameters() -> dict / .setParameters(dict). It seems more symmetrical, and if you can "promise" that (A) setParameters may be called some number of times and (B) endParameters() will *always* be called afterwards, we can put that loop into the config side of the code.
Any reasons why it can't be done this way?
Yes. In the usual case, where you don't need a .endParameters(), then the code will be *much* clearer. You also missed the place where I say ".endParameters() will not be called if it doesn't exist". See axiom 4 -- certainly def setParameter(self, name, value): setattr(self, name, value) (which is the usual case) Is much quicker then def setParameters(self, dict): for name, value in dict.items(): setattr(self, name, value) And another good reason -- this makes it much easier when doing application-level validation, to know what failed: # configuring RSA def setParameter(self, name, value): if not isPrime(value): raise ValueError("not prime") setattr(self, name, value)
Another interesting open question (although not one I'm sure this code has to address) is how to get the respective configuration interfaces to represent object identity. (e.g. I want to mount the *same* web resource on /foo, on /bar)
This code isn't the one that should address it -- this is UI's responsibility. Take *another* look at the way Zope does it.
However, I prefer the register(klass) way, both for clarity and efficiency. Explicit is better than implicit.
Indeed, I've decided I agree, for a different reason -- we do not want spurious options for the user.
Your code has a bug in it, which is a good example of why I like to actually inherit from interfaces :). You don't define "endParameters".
No it doesn't. It's permissible not to have .endParameters(), .setParent() and .initParameters. The first two will not be called if they don't exist.
One more question -- why doesn't the Configurable interface class actually do some things, like data validation? It sounds like it'd be possible (isCorrectInput method on the Parameter classes, or somesuch...)
I've thought about it, and decided against it -- since the UI needs to know so much about the validation anyway, I prefer to putting the knowledge in the UI. Sure, when we realized what is convinient for two UIs, we can have some nice functions to help UIs -- but *outside* the Parameter class. The classical example is that the UI might need to write the validation code in JavaScript, for DHTML forms. Surely, a method written in Python won't help...
On the whole this looks like a good proposal, although I'm still not entirely sure what the final end-user experience of configuration will look like.
Well, I've already gave an example of what it would look like with the command line. Mutatis-mutandis, we can pretty much imagine how to translate it into web-based. Of course, many options still remain, but I don't think I care about UIs: I've specified enough information for the UI -- now the UIs can compete. (We can have 10 different web-based UIs, and choose among them) -- "I'll be ex-DPL soon anyway so I'm |LUKE: Is Perl better than Python? looking for someplace else to grab power."|YODA: No...no... no. Quicker, -- Wichert Akkerman (on debian-private)| easier, more seductive. For public key, finger moshez@debian.org |http://www.{python,debian,gnu}.org