[Zope] Why doesn't setting REQUEST keys work inside <dtml-with REQUEST> ?

hans hans@beehive.de
Fri, 05 Apr 2002 12:56:50 +0100


Don Hopkins wrote:

> Here is the output of a test dtml document, and the source, that
> demonstrates that setting keys of REQUEST inside a <dtml-with REQUEST> does
> not work. Is dtml designed to misbehave this way, or is it a bug? Is the
> <dtml-with REQUEST> superfluous? Why does it change the behavior of setting
> keys? Is there any way to work around the problem? Thanks!
>
>     -Don
>
> test
> This is the test Document.
>
> Foo should be "one", and is "one".
> Foo should be "two", and is "two".
> Foo should be "three", and is "three".
>
> HOWEVER:
>
> Foo is now "three".
> Foo should be "one", and is "three".
> Foo should be "two", and is "three".
> Foo should be "three", and is "three".
>
> BUT THEN:
>
> Foo is now "three".
> Foo should be "one", and is "one".
> Foo should be "two", and is "two".
> Foo should be "three", and is "three".
>
> <dtml-var standard_html_header>
> <h2><dtml-var title_or_id></h2>
> <p>
> This is the <dtml-var id> Document.
> </p>
>
> <dtml-call expr="REQUEST.set('foo', 'one')">
> Foo should be "one", and is "&dtml-foo;".<br>
> <dtml-call expr="REQUEST.set('foo', 'two')">
> Foo should be "two", and is "&dtml-foo;".<br>
> <dtml-call expr="REQUEST.set('foo', 'three')">
> Foo should be "three", and is "&dtml-foo;".<br>
>
> <p>HOWEVER:<p>
>
> <dtml-with REQUEST>
>
> Foo is now "&dtml-foo;".<br>
> <dtml-call expr="REQUEST.set('foo', 'one')">
> Foo should be "one", and is "&dtml-foo;".<br>
> <dtml-call expr="REQUEST.set('foo', 'two')">
> Foo should be "two", and is "&dtml-foo;".<br>
> <dtml-call expr="REQUEST.set('foo', 'three')">
> Foo should be "three", and is "&dtml-foo;".<br>
>
> </dtml-with>
>
> <p>BUT THEN:<p>
>
> Foo is now "&dtml-foo;".<br>
> <dtml-call expr="REQUEST.set('foo', 'one')">
> Foo should be "one", and is "&dtml-foo;".<br>
> <dtml-call expr="REQUEST.set('foo', 'two')">
> Foo should be "two", and is "&dtml-foo;".<br>
> <dtml-call expr="REQUEST.set('foo', 'three')">
> Foo should be "three", and is "&dtml-foo;".<br>
>
> <dtml-var standard_html_footer>

There is a stack of namespaces to resolve names into objects.
initially:
--------------------------------------------> growth
REQUEST
{'foo':...}

But after the dtml-with REQUEST you'll have
--------------------------------------------> growth
REQUEST ! {'foo':....    }
{'foo':...}    !

the with pushes (the content of) REQUEST onto the namespace,
but: REQUEST does not contain itself!!
Therefore, call REQUEST.set('foo', ) will touch the 'foo'-object at the bottom,

while name resolution will find the topmost 'foo' first.
As i understand Python, initially both 'foo's point to the same object,
but asssigning to the topmost 'foo'-object will BIND another value to it
and does not affect the bottom 'foo'-object inside dtml-with.
Also note, that dtml-with has an additional attribute "only",
which limits the depth of name lookup.

--
-------------------------------------------------------------
Who's got only a hammer sees the world as a nail
hans augustin  (software developer)           hans@beehive.de
beehive elektronische medien GmbH       http://www.beehive.de
phone: +49 30 847-82 0                  fax: +49 30 847-82 299