Hi there, I thought I'd figured out DTML methods, but here's something that I intuitely think is possible, but gives me an error (in Zope 1.10.2). It has to do with DTML methods (or documents, I don't think there's a difference) calling each other. My basic understanding: A DTML method is a callable object, that functions as a method of a Zope folder. DTML methods can call other DTML methods, with the #call tag: <!--#call callee--> The call tag doesn't give any return value. The #var tag does; it gives as return value the rendered HTML of the called DTML object. You can supply arguments to your calling DTML methods: DTML method - 'caller' <!--#var "callee(arg='Foo!')"--> DTML method - 'callee' <p>The arg was: <!--#var arg--></p> This works as expected when rendering 'caller', you see: The arg was: Foo! Now, here comes the confusing part -- passing an argument along: First, we rewrite caller to this: <!--#var "callee(arg=newarg)"--> Then we make a DTML method called 'baffle': <!--#var "caller(newarg='Bar!')"--> When I try to view that DTML method, I get an error (appended at the end). Why does this happen? I expect it's not a bug but a failure to understand on my part. In my understanding, methods of objects can pass values on to each other. If it is my error, then perhaps we need some document that describes what exactly is going on when DTML methods call each other, how arguments are passed. I've been browsing through the source but so far I'm not enlightened. I'm wishing for some easy to remember algorithm/structure that's applied here. A related question; in my perhaps broken view of DTML methods as methods can get arguments, the concept of an 'argument list' (somewhat like in Z SQL methods) for DTML methods (and documents) would be useful. I realize acquisition can produce a whole lot of potential arguments (actually being acquired as attributes), but perhaps there should be some way to call up a list of everything that's in the namespace of a particular DTML method (in particular circumstances). Something like that would help my understanding, and might help debugging in general. Regards, Martijn (and here's the promised error traceback from Zope:) <!-- Error type: Error value: callee --> </BODY></HTML> <!-- Traceback (innermost last): File f:\Program Files\Zope\lib\python\ZPublisher\Publish.py, line 877, in publish_module File f:\Program Files\Zope\lib\python\ZPublisher\Publish.py, line 590, in publish (Info: /baffle/baffle) File f:\Program Files\Zope\lib\python\OFS\DTMLMethod.py, line 155, in __call__ (Object: baffle) File f:\Program Files\Zope\lib\python\OFS\DTMLMethod.py, line 151, in __call__ (Object: baffle) File f:\Program Files\Zope\lib\python\DocumentTemplate\DT_String.py, line 513, in __call__ (Object: baffle) File f:\Program Files\Zope\lib\python\DocumentTemplate\DT_Util.py, line 266, in eval (Object: caller(newarg='Bar!')) File <string>, line 0, in ? File f:\Program Files\Zope\lib\python\OFS\DTMLMethod.py, line 147, in __call__ (Object: caller) File f:\Program Files\Zope\lib\python\DocumentTemplate\DT_String.py, line 513, in __call__ (Object: caller) File f:\Program Files\Zope\lib\python\DocumentTemplate\DT_Util.py, line 266, in eval (Object: callee(arg=newarg)) File <string>, line 0, in ? NameError: (see above) -->
Hi Martijn -
Now, here comes the confusing part -- passing an argument along:
First, we rewrite caller to this: <!--#var "callee(arg=newarg)"-->
Then we make a DTML method called 'baffle': <!--#var "caller(newarg='Bar!')"-->
When I try to view that DTML method, I get an error (appended at the end).
Why does this happen? I expect it's not a bug but a failure to understand on my part. In my understanding, methods of objects can pass
In python function arguments that have default values are evaluated at 'compilation' time. So for example the following code raises an error: def callee(a=b): print b Traceback (innermost last): File "<stdin>", line 1, in ? NameError: b
b=4 def callee(a=b): ... print a ... callee() 4 b=5 callee() 4
Seems that Zope will not raise an error when the DTML is originally defined, which is puzzling for me too. Pavlos
Pavlos Christoforou wrote:
Hi Martijn -
Hi Pavlos! [snip my question]
In python function arguments that have default values are evaluated at 'compilation' time.
So for example the following code raises an error:
def callee(a=b): print b
Traceback (innermost last): File "<stdin>", line 1, in ? NameError: b
Yes, but am I indeed using that part of Python? I was thinking I was using (the equivalent of) this: def callee(a, b, c): # (could also use default initializers here) print a, b, c callee(a="foo", b="bar", c="baz") And this works just fine in Python. this does too: hey = "some text" callee(a=hey, b="bar", c="baz")
Seems that Zope will not raise an error when the DTML is originally defined, which is puzzling for me too.
I'm still not quite sure *why* it raises the error at all. If your answer is the right one, I need some more explaining.. :) Thanks, and regards, Martijn
On Thu, 15 Apr 1999, Martijn Faassen wrote:
Yes, but am I indeed using that part of Python? I was thinking I was using (the equivalent of) this:
def callee(a, b, c): # (could also use default initializers here) print a, b, c
callee(a="foo", b="bar", c="baz")
Boy how stupid of me! My answer has no relevance to your question! It is these nice spring days that make me write them. Don't blame me ;-) On Thu, 15 Apr 1999, Paulo Eduardo Neves wrote:
In python it just "looks like" the default values are evaluated at "compilation" time. The above behavior is due to how python manages atribution.
Actually they do get evaluated at 'compilatio' time.
From the python reference manual:
Default parameter values are evaluated when the function definition is executed. This means that the expression is evaluated once, when the function is defined, and that that same ``pre-computed'' value is used for each call. This is especially important to understand when a default parameter is a mutable object, such as a list or a dictionary: if the function modifies the object (e.g. by appending an item to a list), the default value is in effect modified. This is generally not what was intended. I remember at one point Tim Peters wrote an example to demonstrate some issues relevant to the above which included some nested class and function definitions. He claimed that if anyone could predict what will happen when the code is run then she/he indeed understands what goes on during class definitions. I don't have the code but I remember at the time I failed miserably! Pavlos
Hi Pavlos, Pavlos Christoforou wrote:
In python function arguments that have default values are evaluated at 'compilation' time.
...
b=4 def callee(a=b): ... print a ... callee() 4 b=5 callee() 4
In python it just "looks like" the default values are evaluated at "compilation" time. The above behavior is due to how python manages atribution. When I execute the commands: a = 3 b = a a = 4 What I'm doing is a = 3 #creates an integer object '3' and points a to it b = a #points b to the same integer object that a points to a = 4 #creates an integer object '4' and points a to it, b still points to the old 3 See what happens when you just change the object that is pointed:
b = [3] def f(a=b): ... print a ... f() [3] b[0] = 1 f() [1]
Confusing, no? I've needed some time to grok it. -- Paulo Eduardo Neves PUC-Rio de Janeiro Pager: Central: 292-4499 cod. 213 99 64 ou use a URL: http://www.learn.fplf.org.br/neves/mensagempager.html
participants (3)
-
Martijn Faassen -
Paulo Eduardo Neves -
Pavlos Christoforou