[Grok-dev] concerns about grokcore.component.provides

Martijn Faassen faassen at startifact.com
Wed Sep 9 10:02:55 EDT 2009


Hey,

Gary Poster wrote:
[snip]
> However, I'm also more convinced that the name of  
> "grokcore.component.provides" is a problem.  

I agree it's a problem, as this isn't the first time it came up.

> My current preference is  
> for "provides_adapter".  Reading this, I understand what the grok  
> directive is doing.

One issue with this naming is that grok.provides is also used for global 
utility registration right now. You'd also need a grok.provides_utility 
that does the same. The principle is to reuse directives if they do 
something similar enough, which one argue (also from the underlying 
code) is the case here.

I also think there's a bit of a DRY violation in saying 
provides_adapter. The base class indicate it's an adapter. The 
directives specify how it's an adapter. In your example you have your 
own base class (CookbookTopLevelObject) that obscures this somewhat. One 
needs to trace base classes. But this is a fairly common thing an object 
oriented developer needs to do anyway, and it won't be long before they 
realize it's an adapter.

(this is an argument for a different-style martian that allows one to 
indicate what is being registered not by base-class but by directive: 
grok.adapter(), grok.view(), etc. That's another discussion and a much 
bigger topic, though)

We still have the confusion of the word provides, which in ZCML means it 
provides an *interface*. I guess here it would mean "provides an adapter 
of kind IFoo".

Let's think about naming some more. We're writing a class. It implements 
some interfaces. We now want to look up an instance of this class. We do 
this by asking for an instance that provides one of these interfaces. In 
cases of adapters, this instance is created on the fly, in case of 
utilities, it's been registered already.

So what do we call: "this class makes instances that will provide 
interface X when looked up as an adapter/utility" notion?

Let's check the thesaurus.

The class is a factory for IFoo adapters (or the IFoo utility). 
Therefore, we could consider grok.factory(IFoo). There's a slight 
overloading with the factory notion in Zope 3 (there's such a directive, 
I think?), but it doesn't appear to be a commonly used notion (and 
certainly not in Grok). Also I have the feeling there's a subtle 
difference between the way grok.context and grok.layer are used and 
grok.factory, but perhaps that's just me.

The class creates IFoo adapters (or the IFoo utility). Therefore, you'd 
write grok.creates(IFoo).

Other possibilities might be grok.delivers or grok.produces.

Right now, I think I like 'creates' the best.

[snip]
> If you do a "from foo import bar" style (still advocated in some  
> quarters, and used at Canonical)

[I tend to do quite a lot of this too. I don't buy the arguments for 
repeating.a.dotted.name.everywhere; in my experience it produces more 
cycles (and needs for deferredimport) than a few 'from foo import bar' 
in a package. Especially when you create a clean interface in a 
package's __init__.py which I really like]

> then the distinction is even more  
> stark, in my opinion.  Current:
> 
> class FeaturedCookbookLink(CookbookTopLevelObject):
>      """A link to the currently featured cookbook."""
>     implements(ICookbookObject, ITopLevelEntryLink)
>      provides(ITopLevelEntryLink)

For grokcore.component, I'd recommend doing this:

import grokcore.component as grok

(or: from grokcore import component as grok)

[Inside a package, I often use the pattern where I import a module 
instead of an individual name. still a from import]

> My read: huh?
> 
> Proposed:
> 
> class FeaturedCookbookLink(CookbookTopLevelObject):
>      """A link to the currently featured cookbook."""
>     implements(ICookbookObject, ITopLevelEntryLink)
>     provides_adapter(ITopLevelEntryLink)
> 
> My read: ah so!

What do you think about:

class FeaturedCookbookLink(CookbookTopLevelObject):
     grok.implements(ICookbookObject, ITopLevelEntryLink)
     grok.creates(ITopLevelEntryLink)

Regards,

Martijn



More information about the Grok-dev mailing list