[Grok-dev] Re: Grok nomenclature

Martijn Faassen faassen at startifact.com
Thu May 1 04:36:17 EDT 2008

Martin Aspeli wrote:
>> If you say:
>> import grok
>> from plone.app.portlets.portelts import base
>> class MyPortletAssignment(base.Assignment):
>>      grok.grokked()
>> It'll be grokked (if a grokker was registered for base.Assignment of 
>> course). 'grok.grokked()' just adds the IGrokked interface to these 
>> classes. You then are supposed to use directives where needed.
> There's a slight problem with that, in that if you did implements() as 
> well, it may override, but I'm sure this could be worked around.

implements() shouldn't override. We can certainly write two directives 
that add interfaces to a class without interfering, I'd say. After all 
implements already deals with base class implementation correctly.

> How about:
>  class MyPortletAssignment(base.Assignment):
>      grok.as('plone.portlet')
> This would look up a named grokker called 'plone.portlet' that would be 
> able to grok this type of class. 

This sounds like repeating yourself, if the class already can signal 
what class could be used.

> I would also make it possible to 
> parameterise this, so e.g.:
>  class MyPortletAssignment(base.Assignment):
>      grok.as('plone.portlet', name='my_assignment', for_=IFoo)
> In pseudo-code, grok.as() would be:
>  def as(_grokker_name, **kwargs):
>      grokker = getUtility(IGrokker, name=_grokker_name)
>      context = sys._getframe(1)
>      grokker.grok(context, **kwargs)
> This is a fairly fundamental shift, though. :)

Yeah, this sounds like reimplementing ZCML as grok directives.

>> These directives can be defined by grok. In this case the semantics of 
>> these directives should be the same, or very similar, to the semantics 
>> of the directives as used in Grok ('grok.context()' should not 
>> suddenly be used to set the view name, say).
> Sure. However, as soon as I needed another descriptor (to set the 
> portlet manager, say), I'd need to venture outside the grok namespace, 
> since I couldn't invent grok.portlet_manager('foo') easily. More on this 
> below.

Yes, then you'll have to do this. This is like saying as soon as I need 
a function that's not in the package I'm using, I need to import it from 
another package. :)

> Right - in the grok.as() example above, I actually imagined descriptors 
> moving to named parameters to the grok.as() function.

This is a huge shift, as you say before. I'm not much in favor of it. 
Grok directives have the benefit that they typically take one or a few 
parameters, not a whole slew. This makes it possible to leave individual 
ones out. You can do this with keyword parameters, but I think it makes 
it much less readable. You'd also need a very different implementation 
of directives to be able to do a declarative definition of the 
defaulting rules (and we're moving towards such declarative 
definitions). Note that Uwe Oestermeier has such a system - it's much 
closer to ZCML than Grok is, but is inline in Python code.

> To someone not 
> familiar with the details of what is Grok what isn't Grok, the 
> distinction between grok.* and base.* would be fairly arbitrary.

Perhaps. I think people are quite familiar with the concept of 
namespaces. I'd need to see more examples of custom directives use first 
to see whether this is really a problem.

>> This will allow domain-specific extensions to the Grok language to be 
>> in their own namespace, and there won't be an explosion of classes, 
>> one for non-grok and one for grok, where this is not necessary. If 
>> ZCML can register it, one should be able to register it with Grok too.
> That's a very good point - I agree with this meme very much, actually.
> Of course, in some cases, it makes sense to have a Grokish base class. 
> For portlets, for example, we're actually condensing three classes to 
> one with Grokish behaviour and may want to make that explicit.

Agreed, it makes sense in quite a few cases, but then it's not a simple 
exercise of duplicating classes. It's a design exercise thinking about 
how this could be made more easy to use. In that case, I'd not want a 
'grok.grokked' directive to be there. This I see as a very "grokkish" 
exercise, though of course we need to determine on a case by case basis 
on whether the result would be actually part of Grok.

>> * introduce new directives where that makes sense, and import the 
>> directives from the same place as the base classes. I think these 
>> things should be semantically near.
> +0.5 - I think this is clear when it comes to directives, certainly. For 
> other things (base classes - are there other primitives we need to 
> consider?), conventions may be useful.

Yes, perhaps. I'm wary of such conventions, as we don't need them in 
Grok, and I prefer code without such conventions, trying to exploit 
namespaces in Python instead to mark conventions. I don't think a 
grokked class is as fundamentally different than an interface is from a 
class (where we do have a consensus about the I* convention).

I realize that using conventions is more attractive if you are evolving 
code forward that doesn't use Grok yet. That said, I still hope for an 
end result of the evolution where there is a package which just has 
classes, and that knowledge of whether it needs to auto-register is 
actually not very relevant to the programmer. It's an implementation 
detail, just like whether a meta-class is in use should be an 
implementation detail (where, as you'll note, no conventions are in use 
to mark them out either).



More information about the Grok-dev mailing list