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:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to