- Amos
I like this proposal a lot. Moving toward explicit interfaces is a Good Thing. How will the new security settings be spelled? Will __ac_permissions__ still be used?
- JimFulton (Aug 1)
__ac_permissions__ will be used to
set permission security.
At the Python level, we should provide an interface
for spelling the other types of access (e.g.
AccessControl.Public (("Anonymous",) ))
At the ZClass? level, we'll need to provide a way of
indicating the special cases.
- Brian (2000/08/03)
I've modified the proposed convention slightly
to be a bit more readable: ZInterfaceName_MethodName instead of
ZInterfaceName_methodName. Argument welcome :^)
- PJE (Aug 3)
Something bugs me about the ZInterfaceName_MethodName business. I think it's mainly that it sounds like a bureaucratic non-solution to the problem of writing good method names. I personally would prefer a more english-like convention. For example, "getObjectManagerItems" instead of "ZObjectManager_getItems" . With the former I can still read my code, even if it's a bit verbose. :) How about making the convention "verbInterfaceSubject"? e.g.:
setObjectManagerObject
delObjectManagerItem
addRoleManagerRole
I'm not sure this would cover all possibilities, but it's an extensible protocol that takes care of getting the interface name in there (which I do like).
- Paul
First, someone please tape a sign to Jim's monitor that says:
"It's" means it is
"Its" means possessive
:^)
- JimFulton
Hey, I can't help it if the English language is
broken.
Next, I think Jim left off one other magic naming convention, which
is _v_ .
Regarding the solution, I agree with Phillip in my distaste for the
rules regarding names. It just doesn't seem to jibe with what people
would expect from other systems. Phillip's choice feels very DOM-ish,
which I view as a good thing. (At some point I'd like to see the DOM
become, where appropriate, more of an official API for Zope, but
that's a tangent.)
The heavy verbosity of extra typing for DTML authors is going to cause
a backlash, especially when combined with the backlash we'll already
inherit from the DTML cleanup.
How do other systems, such as Beans/EJB where there is a large pool of
third party suppliers, avoid this kind of namespace isolation problem?
Do they simply force people to specify the namespace? Or do they not
have the problem so much since they don't have aquisition (and thus
implicit access to methods from other contexts)?
- JimFulton (Aug 4)
This is an API naming convention. _v_ names don't belong
in an API.
My proposal is based on the Python C API naming
convention, which I have found to be extremely usable and readable.
I don't like mixing the interface name in with the method name.
I find this makes it harder to pick out and to remember the method
name. Breaking the name into two parts makes it easier for me
to remember. For example, remembering getItem and ObjectManager
separately is much easier than remembering getObjectManagerItem ,
which I would approach by remembering getItem and ObjectManager
and applying the complex application rule.
- Paul (Aug 9)
I don't think the Python C API convention provides much of a
useful analogy, as it only exposes the verbosity to people working
at the C level. I've never worked at the C level, so I've never
been exposed to prepending PythonObject_ (or whatever it
is called) on everything.
- Jim (Aug 18)
Zope namespaces, like the C global namespace, can get quite
large. This is especially the case with object managers.
Further, the C namespace is managed by multiple developers
who can't keep track of other developer's names without
some additional organizing facility.
There is a very similar problem with object managers.
The author of an object manager cannot be aware of the names
placed in the object manager by it's eventual users/managers.
Similarly, the user of an object manager is unaware of the
methods the object author has created or may create.
In general, Python users never have to see method names that are
polluted with namespace stuff to avoid collisions. At least I
haven't seen it.
- Jim (Aug 18)
Python objects aren't uses the same way Zope object managers
are. The author of a Python object doesn't have to worry
about the user of the object adding arbitrary names to the
object space.
Regardless of Python as an example, it is important to recognize
that there is a chance that Zope users (who probably don't
frequent the Zope Developer Home and track these proposals) are
going to have a backlash. This backlas will likely be worse
than the problem that is being addressed.
- Jim (Aug 18)
I'm not sure what you mean by a Zope user. User's who
manage content or simply use the UI would not deal with these
methods. Only a Programmer would be aware of them.
As for the verbosity, it is necessary to reduce the likelihood
of name conflicts. This is important for object managers to
avoid conflicts between method and sub-object names. Of course,
my proposal and Phiilips alternative are equally verbose.
WRT other systems, I think you'd find a convention like
the one I proposed more common in systems with multiple inheritence
and mix-in classes. Of course, Zope has the added issue that
object managers combine their method and sub-object namespaces,
which is the main issue here.
- PJE (Aug 4)
To be honest, my first preference in a naming convention (if conflict avoidance is a requirement and there are many such interfaces) would be object.interface.method . e.g. anObject.ZObjectManager?.getItem("foo") . That is, don't try to use a convention to do namespace resolution when the language already has a provision for namespace resolution. :) Unfortuntately, using it would add an even more undesirable level of overhead.
- Jim (Aug 18)
Introducing a namespace for each interface is somewhat
apealing, however, then one has to worry about conflicts
with the interface names. While there would be fewer interface
names than methods, the interface names would be simpler
and more likely to conflict.
Nonetheless, I am not entirely convinced that anything needs to be done at all. Conflicts between method names and subobject names seems to me very unlikely, if method names are simply clearly written. It seems more likely that conflicts would be in the area of mixin classes. Again, this is a problem with the origin names. If you are mixing two interfaces with different semantics for "getItem()", it sounds like a job for an adapter or other intermediary. The reason I like having an indication of the interface in the method name is not because I want to eliminate conflicts, but because it helps give a clue as to what the method's purpose is. But if the methods were better named in the first place (e.g. "getSubobject()" vs "getItem()") they would be more clear and name conflicts would be much less of a problem. IMHO, many Zope interfaces suffer from a generic naming style that also tends towards solution-domain naming rather than problem-domain naming. This in itself tends to make names more homogeneous, and therefore more conflict-prone.
- PJE (Aug 4)
By the way, the proposal mentions an explosion of Zope interfaces (presumably GUI's and the like) as being an issue for namespaces, but these are actually the easiest and least offensive (conceptually and performance-wise) to be implemented using an object.interface.method naming, since then the interface object can be acquired, or simply inserted into a base class without having to manage its implementation to the same degree.
- ChrisM (8/4)
I'm good with what Jim proposes. It's important that we get timely consensus on a way of spelling API stuff, IMHO, so I'm more concerned that it gets decided than I am about how it gets spelled.
- DLPierson? (8/9)
I think the increased verbosity will be a very big issue with DTML programmers. Maybe this will be tolerable if and only if the renamed PythonMethods are used to make DTML programming extinct, but I'm unconvinced. Even with shorter names, DTML tends to enormous lines that don't fit on anyone's screen in many hands.
Other than the verbosity issue I find this proposal less obnoxious than Hungarian notation, but inferior to a real namespace solution. For one thing, real namespace solutions generally support prefix abbreviations. Certainly all of: Python, XML and Lisp do (I can't remember about C++ right now).
As a minor tweak, I'd suggest DC have some additional (short!) convention to reserve a piece of namespace for official Zope stuff. We'll still need some sort of cooperative prefix registry though.
- Toby Dickenson (2000-08-10)
I like prosed naming system, except the requirement for a leading Z. Is ZObjectManager_GetItem any better than ObjectManager_GetItem?
Also, today's Zope will not allow a subobject to be created if its id clashes with a method implemented by the container object. I suggest it would be appropriate to extend that restriction to all id's of the appropriate pattern, so that subobjects can not clash with future
interfaces.
- MrTopf (2000-08-10)
wouldn't this distinction between Interface and method be unneccessary at all if we would have different classes for interfaces and actual objects (model/view architecture)? I actually would like some simpler names than the existing ones like add(), delete(). I am actually no friend of prepending manage_ always and everywhere.. The problem is of course that splitting objects into model and view would be hard to do with the existing web management interface as you call "manage" directly on the object (depends on what this object then actually is, the model class or the view class). Thus as compromise I would also prefer the object.interface.method naming as then both parts are separated at least internally (or could be).
- Brian (2000/08/10)
Note that interfaces are not implementations,
they are descriptions of supported functionality. So
object.interface.method would have to mean that interface was
not really an interface, but rather some sort of namespace that
contained the given interface implementation on object . Actually
implementing that would be a pretty drastic change, I think.
- PJE (2000/08/15)
Not really. All you need is an ExtensionClass?, let's call it "InterfaceImplementation" or "Implementation" for short. You define a method-call hook on it that rebinds the called method to the aq_inner.aq_parent of the implementation object. Poof! You're done. There's a bit of overhead, especially since you now have to refer to other methods of the same interface as self.interface.otherMethod(), but you could also do the rebinding such that the call signature of implementation methods is def implMethod(self,impl,...) and so there's a shortcut to refer to other implementation methods. This is only one of several possible ways to implement this concept.
It should be noted that the "subobject named for interface that provides implementation" is a very useful paradigm, because it allows you to create objects which "mix and match" implementations of an interface, and perhaps most importantly, it eliminates diamond-shaped multiple inheritance!
- Brian (2000-08-17)
I meant "drastic change" from a conceptual
viewpoint rather than a technical one. We have enough (too many)
"new paradigms" already - my standing goal for the future is to
try to make Zope more familiar, not less so :^)
Jeffrey (2000-08-29) says:
I like Jims proposal, at least for (or especially
for) Protocols. As I'm writing an proposed Interface to add into my
write locking proposal that object authors would have to support (although
not many - a few common base classes would likely have them implemented).
If someone wants to write an object that plays nice with the (proposed)
write locking machinery, the following makes sense to me:
class SooperContent(allSortsOfSuperClasses,...):
""" my sooper content class """
__implements__ = (WriteLockingInterface?, ...)
def WriteLock_grantLockToUser(self, user):
""" stuff """
def checkOut(self, REQUEST):
" my own method, which checks out the object to authenticated_user "
...
self.WriteLock_grantLockToUser(self, user):
I wouldn't know how to write in my support for the WriteLockingInterface
in the obj.interface.method format. An inner class? A mix in class
(or otherwised referenced) that would be only the support for that
interface? (SooperContentWriteLocking )? Playing games with rebinding?
Ouch. That, I believe, would make having new developers properly support
and implement protocols correctly - even harder!.
- PJE (2000-08-30)
-
See example:
class SooperContent(allSortsOfSuperClasses,...):
""" my sooper content class """
__implements__ = (WriteLockingInterface, ...)
class WriteLock(InterfaceImplementation):
def grantLockToUser(self, impl, user):
""" stuff """
...
WriteLock = WriteLock()
def checkOut(self, REQUEST):
" my own method, which checks out the object to authenticated_user "
...
self.WriteLock.grantLockToUser(user)
It would seem to me that this is actually a pretty straightforward way of implementing such protocols. (Note: I would suggest the interface in the example be named "WriteLocking" rather than "WriteLock"). The method rebinding magic is implemented in the InterfaceImplementation class, not in your specific implementation. The only bit you have to worry about is the extra "impl" parameter, and you could always have a SimpleImplementation class that didn't pass it. You only need the extra parameter if your implementation itself has properties or methods you need quick access to (as opposed to saying "self.WriteLock.foo()" in the implementation, you can simply say "impl.foo()").
Anyhow, I have previously found this approach to be quite useful in web-based systems like Zope. In one system one of my developers worked on, we had "Machine" objects which had a "Drives" interface. The Drives interface had an index_html method which displayed the machine's hard drives and offered links to other methods of the Drives interface, using the usual relative linking approach. At the time, we called the Drives object a "Method Container", as we weren't thinking so much of interfaces per se, as a clean way to group and organize functionality without having a crowded namespace and complex names to compensate for it. That is, we prefered self.Drives.add() and self.Cards.add() to self.add_drive() and self.add_card().
- Jeffrey part ii
Oh, I'm not fond of the !ZInterfaceName_MethodName
spelling. The Z at the beginning I could live with (it's common practice
in Cocoa frameworks. WODisplayGroup is a WebObjects specialized
subclass of EODisplayGroup from the enterprise objects framework). The
MethodName bit I don't like as much as methodName , starting the method
name lower case is a bit of a visual cue (to me anyways) that the actual
method name starts there. ZWriteLock_GrantLockToUser(self, user) does
start to look bad, especially in cases of smaller names like lock and
unlock (def ZWriteLock_Lock(self): just doesn't look quite right to
me, but that's my own personal obersvation after writing things the
InterfaceName_methodName way earlier in the day).
|