[Grok-dev] Re: Grok nomenclature
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):
>> 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):
> 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
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