specifying namespace stacks in <dtml-with>
I was thinking about something I'd consider a useful addition to the <dtml-with> tag; I'd like to get other people's opinions, especially about a couple syntax issues. Problem: In part because of the combination of the dtml namespace stack and acquisition, it's often hard to get exactly the name resolution you want in Zope. For example, I think it's really useful to want the following: "Call an object, found by acquisition, using its "natural" namespace, except include a small number of symbols found in the local namespace. When evaluating the local symbols, do so in the local namespace." Why is this useful? Because it cuts down on accidental interference of the local namespace in the evaluation of an object, which acquisition exacerbates because it multiplies the number of symbols in the local namespace. I'd even go as far as to say that the above action is what most people want to do most of the time. How do you do it? If you do: <dtml-with object> <dtml-with expr="_.namespace(name1=local_object1, name2=local_object2)"> <dtml-var object> </dtml-with> </dtml-with> (or the equivalent using an inner "let" tag instead of "with") you get the right nesting, but "local_object1" and "local_object2" are evaluated in "object"'s namespace, not the local one. I *think* the only way to do it right (I haven't tried it) is: </dtml-let ns="_.namespace(name1=local_object1, name2=local_object2)"> <dtml-with object> </dtml-with ns> <dtml-var object> </dtml-with> </dtml-with> </dtml-let> That way, you can get a namespace evaluated in the local scope onto the top of the namespace stack to override the object's symbols. You've got to go through contortions to swap the order of the namespace stack without introducing unwanted evaluation side effects. Yuck! I think is would be much cooler, and more general, to be able to specify a namespace stack as a list for <dtml-with>: <dtml-with "[_.namespace(name1=local_object1, name2=local_object2), object]"> </dtml-var object> </dtml-with> The "with" tag's entire expression would be evaluated in the local scope, *then* a namespace stack would be constructed, using elements of a list. If you had several objects already, the syntax is even cleaner: <dtml-with expr="[object1, object2, object3]"> ... </dtml-with> In short, this construct lets you build a well-defined namespace stack without worrying as much about unwanted scope interaction. It's even not that hard to write the implementation, except for a couple questions. -- First, the "mapping" attribute to "with" is per-namespace; how do you specify it for elements of the stack? (The "only" attribute is okay, it is specified once per stack.) It would be limiting to say that all namespaces pushed onto a stack would need to be all be mappings or all be objects. -- Second, is the expression for "with" currently ever a sequence? If so, then you'd have to recognize and distinguish between the old and the new usages. I don't think there's much of a problem here, although the "with" tag code does do a little checking about whether its expression is a tuple. -- Finally, what's the natural order of the stack? If you give the argument "[a, b, c]" to "with", is "a" or "c" on the top of the namespace stack? I'd probably say "a". I'd appreciate any ideas/suggestions others may have. Thanks! Michael Halle mhalle@media.mit.edu
participants (1)
-
Michael Halle