You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@velocity.apache.org by Christoph Reck <Ch...@dlr.de> on 2002/03/26 09:18:09 UTC
Re: macro arguments may change implicitely - why not store arguments in
local context ?
Hi,
this is why I've been proposing to implement a
#local( $var1 $var2 ... $varN )
...
#end
directive to allow using $var1-N locally without touching whatever these held
externaly. This would greatly enhance the usability of a predefined macro
library. Also it would help creating independent template fragements that can
be #parsed into other templates.
Creating such a #local directive is an easy task: just take the #foreach
directive source and modify it to do what you want - either by saving the
var1-N the original context containsKey(varX) or by chaining a new context
onto the current one with the var1-N predefined (e.g. to Boolean.FALSE) on
it.
I'm currently working on another Swing-based project and have no chance to
write and test this, but anyone could take up this chore...
:) Christoph
Claude Brisson wrote:
>
> I'd like to discuss a strange behaviour (already mentionned sometimes, but without any concluding point, imho), and to make a
> proposal.
>
> When velocimacro.context.localscope is false, a macro may implicitely change the actual value of its arguments by changing some
> external variable implied in their calculation.
>
> This is due to the fact that each time a non-constant argument is evaluated in a macro, it is re-evaluated with the global context
> that may have been changed by the same macro.
>
> For instance, as shown in example 1, if a #foreach or a #set directive inside a macro uses a reference name similar to the name of a
> reference passsed to the macro, then the actual value of the parameters may also change in the same time.
>
> ---------------------
>
> ## Example 1 :
>
> ## outputs "1 ! a b c" instead of expected "1 1 1 1 1"
>
> #macro (test $arg)
> $arg ## -> 1
> #set($i = '!')
> $arg ## -> !
> #foreach ($i in ['a','b','c'])
> $arg ## -> a b c
> #end
> #end
>
> #set($i = 1)
> #test($i) ## outputs "1 ! a b c" instead of expected "1 1 1 1 1"
>
> ---------------------
>
> This may be seen as a small side effect, but it can lead to very ankward behaviours in some situations... especially when dealing
> with macro recursions.
>
> ---------------------
>
> ## Example 2 : (partial)
>
> #macro (disp_node $node)
> #foreach ($child in $node.children())
>
> $child.name is a child of $node.name
> ## ^^^^^^^^^^ (I hate proportional fonts)
> ## "$node.name" evaluate to (external) "$child.name", which equals (internal) "$child.name"
> ## so for a basic tree (grandparent-parent-grandson) we get the output "grandson is a child of grandson"
>
> #disp_node($child)
> #end
> #end
>
> ---------------------
>
> This recursion problem should also be solved if #foreach directives avoided to store their working variables in the global context,
> but it's another point.
>
> I finally made it out for my personal stuff, by the mean of two or three dreadful workarounds, but here is my point :
>
> Why couldn't macro directives only evaluate once their arguments at the moment they are called and save them in their local
> context ?
>
> This sounds too simple... do I miss something ?
>
> As shown in example 3, only vicious minds (like mine here, for a didactic purpose) may try to exploit constructively this behaviour.
> Otherwise, it's rather strange (and time consuming) to re-evaluate arguments each time.
>
> ---------------------
>
> ## Example 3 : outputs "hello folks"
>
> #macro (print_twice $value)
> $value $value
> #end
>
> #set ($myarray = ["hello","folks"])
>
> #print_twice($myarray.remove(0))
>
> ---------------------
>
> Depending on the followup, I'd be glad to try to contribute attenant patches.
>
> Thanx for reading up to that point.
> And last but not least, thanx a lot to the support team.
>
> Sincerely,
>
> CloD
>
> --
> To unsubscribe, e-mail: <ma...@jakarta.apache.org>
> For additional commands, e-mail: <ma...@jakarta.apache.org>
--
:) Christoph Reck
--
To unsubscribe, e-mail: <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>