[Zope3-dev] Allowing views to be registered for classes rather
than interfaces.
Steve Alexander
steve@cat-box.net
Thu, 17 Jul 2003 13:59:41 +0300
> Tres has argued (with merit) that only interfaces designed to support
> multiple implementations should go in a separate hierarchy.
I support Tres' argument.
I think there is value in having a separate place for interfaces that
are meant to have a variety of implementations. We might call these
"standard interfaces" or somethig like that. We should be careful about
changing the contract of a "standard interface" once it has been made
available in released software.
I don't see any harm in putting other interfaces along with their
implementations.
An idea I was kicking around with Martijn Faassen is to have an
automatic way of making an interface for a class.
The idea is that when you are prototyping a class, you don't want to
keep an interface in synch with it. Rather, you just want to write and
modify the class. However, you still want to be able to hook up views
and adapters etc.
So, we use the common convention that names begining with an underscore
are "private" and all other names are part of the interface.
It might look like this:
class Foo:
nonceInterface()
def bar(self, arg):
"Documentation"
# do something
baz = 23
def _spoo(self):
# do something private
_fish = 99
The nonceInterface() class advice creates an interface called
"Foo.interface" that defines the method bar and the attribute baz. It
does not define _spoo or _fish because they start with an underscore.
This is a common convention for attributes and operations that do not
form part of the public API of an object.
From zcml, we can refer to Foo's interface as
<require permission="zope.View" interface=".Foo.interface" />
To make this work, and make the interface picklable, the
nonceInterface() advice needs to do the following:
1: synthesize an interface based on the contents of the class
2: make the class implement that interface
3: inject the name 'Foo.interface' into Foo's module
4: set a class-only descriptor on Foo that gets you access to the
interface, in the name "interface"
and maybe also...
5: set a class-only security checker on the class so that access to the
"interface" attribute is allowed
If you want to use schemas with a nonceInterface, you can define the
schema and then have the nonceInterface use the fields of that schema to
override the fields gleaned from inspecting the class.
class _IFooSchema(Interface):
baz = IntField(title=u'for baz things')
class Foo:
nonceInterface(_IFooSchema)
def bar(self, arg):
"Documentation"
# do something
baz = 23
Why nonceInterface()? It is like a "nonce word".
From Webster's Revised Unabridged Dictionary (1913) [web1913]:
Nonce \Nonce\ (n[o^]ns), n. [For the nonce, OE. for the nones, a
corruption of for then ones, where n. in then is a relic of
AS. m in [eth]am, dat. of the article and demonstrative
pronoun, E. the. See {For}, {Once}, and {The}.]
The one or single occasion; the present call or purpose; --
chiefly used in the phrase for the nonce.
The miller was a stout carl for the nones. --Chaucer.
And that he calls for drink, I 'll have prepared him A
chalice for the nonce. --Shak.
{Nonce word}, ``a word apparently employed only for the
nonce''. --Murray (New English Dict.).
From WordNet (r) 1.7 [wn]:
nonce
n : the present occasion; "for the nonce" [syn: {time being}]
--
Steve Alexander