[Zope-dev] local/set

Phillip J. Eby pje@telecommunity.com
Fri, 10 Dec 1999 15:17:46 -0500


At 01:40 PM 12/10/99 -0600, Evan Simpson wrote:
>"Phillip J. Eby" wrote:
>
>> Let: allows read-only variables to be computed whose values are usable
>> within a DTML nesting scope.
>>
>> Local: allows writable variables to be computed, whose values are usable
>> and changeable within a DTML nesting scope.
>>
>> Set: singleton tag that changes the value of a "local" variable, as long as
>> it was defined in the innermost surrounding "local" block.
>
>Given these use-cases, consider the following variant of Let:
>
><dtml-let x="1+1" person: firstname=" 'fred' " weight="180">
>  <dtml-var x>, <dtml-var firstname>, <dtml-var "person.weight">
>  <dtml-call "person.set('weight', 185)">
>  <dtml-var weight>
></dtml-let>
>
>That is, every variable set after a colon-terminated singleton 'foo:' is also
>a mutable (through .set()) attribute of 'foo'.

I like it.  In a lot of ways, it's much more elegant.  For example, you can
use set at multiple nesting levels.  Except for one thing.  If you are
calling "untrusted" code from your DTML, you have no way to prevent that
code from changing the value of the object's fields, without doing
something like:

<dtml-let person="_.None"><dtml-call untrusted_code></dtml-let>

However, that is probably not such a bad deal.

Let me throw out a counter-proposal, however.  Suppose that the
_()/_.namespace() functions were changed to return writable namespace
objects?  Then, your example could be written as:

<dtml-let x="1+1" person="_(firstname='fred',weight=180)">
 <dtml-var x>, <dtml-var "person.firstname">, <dtml-var "person.weight">
 <dtml-call "person.set('weight',185)">
 <dtml-var weight>
</dtml-let>

And then both dtml-set and dtml-local can go away, and the : syntax isn't
needed.  Also, the above example could then be written as:

<dtml-with "_(firstname='fred',weight=180,x=1+1)">
 <dtml-var x>, <dtml-var firstname>, <dtml-var weight>
 <dtml-call "set('weight',185)">
 <dtml-var weight>
</dtml-with>

at least if you don't need to interact with multiple "local-variable"
namespaces simultaneously.  Everybody wins.

Last, but not least, I should probably note that my enthusiasm at the
simplicity and elegance of these solutions from a programming standpoint is
matched only by my misgivings about how much harder they may be to teach
someone how to use than local/set.  But I guess I'll withhold judgment on
that until I've had to do it.  :)