[Zope] dtml-var weirdness
Joseph A Knapka
jknapka@earthlink.net
Mon, 18 Feb 2002 10:39:24 +0000
"Thomas B. Passin" wrote:
>
> [Joseph A Knapka]>
> > Stupid question of the day:
> >
> > Why might the following code result in a KeyError? It does
> > in some contexts under Zope 2.5.0.
> >
> > <dtml-if expr="REQUEST.has_key('xyz')">
> > <dtml-else>
> > <dtml-call expr="REQUEST.set('xyz','Hello world')">
> > </dtml-if>
> >
> > Sometimes the next line results in a KeyError, value 'xyz':
> >
> > <dtml-var name="xyz">
> >
> > In such cases, this works fine:
> >
> > <dtml-with REQUEST only>
> > <dtml-var name="xyz">
> > </dtml-with>
> >
>
> You set the property named "xyz" in the REQUEST, and you can be sure of
> referring to it if you say "REQUEST['xyz'] or "REQUEST.xyz", as in
>
> <dtml-var "REQUEST['xyz']">
Yes, but why can I *not* be sure of referring to it by
<dtml-var xyz>? (I forgot to mention, this code appears
with a DTML document, not a method.)
> Note that using "expr=" is redundant - you can always omit it.
Though the Zope docs recommend against doing so, and I can
see why: <dtml-var "xyz"> vs <dtml-var xyz> have different
semantics, and are visually not easy to differentiate.
> So your
> example could be written:
>
> <dtml-if "REQUEST.has_key('xyz')">
> <dtml-else>
> <dtml-call "REQUEST.set('xyz','Hello world')">
> </dtml-if>
>
> or, a bit simpler and more readable,
>
> <dtml-if "not REQUEST.has_key('xyz')">
> <dtml-call "REQUEST.set('xyz','Hello world')">
> </dtml-if>
>
> Referring to "REQUEST['xyz']" always works. But as long as no other
> namespace has been inserted into the mix, you can also get the value in any
> of these ways:
>
> 1) <dtml-var "xyz">
> 2) <dtml-var xyz>
> 3) <dtml-var "_['xyz']>
>
> That's because REQUEST properties are specially made available to its
> owner's namespace for convenience.
>
> These last three versions all really ask for the same thing, just in
> slightly different ways:
>
> 1) asks for a Python variable named "xyz". Python looks for this variable
> in the namespace stack, which normally starts with the namepace of the dtml
> document containing the code (if it is in a dtml document, otherwise
> different rules apply).
>
> 2) asks Zope for a variable named "xyz". Zope looks in its namespace stack
> to find it. It's normally the same namespace stack that Python would be
> using, so this is equivalent to 1) in most cases.
>
> 3) is an alternative way to ask for the same thing as 2). It's advantage is
> that the name of the variable does not have to be known when you write the
> code - any string will do.
>
> If the code is in a dtml method, the method does not have its own namespace.
> What namespace it uses, and therefore whether it can find the right
> variable, depends on how it is called, thus the results can vary. There
> have been many threads in the list about this.
Yes, I understand all that. My question, to put it very
explicitly, is this:
Since I'm checking to see whether REQUEST has a
key 'xyz', and setting it if not, then by the time we get
to the <dtml-var xyz> line, REQUEST definitely *does* have
an 'xyz' key; and since REQUEST is undoubtedly in the
namespace (right?), how can <dtml-var xyz> possibly result
in a KeyError?
Thanks,
-- Joe
"I should like to close this book by sticking out any part of my neck
which is not yet exposed, and making a few predictions about how the
problem of quantum gravity will in the end be solved."
--- Physicist Lee Smolin, "Three Roads to Quantum Gravity"