You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@velocity.apache.org by Guillaume Polet <gu...@gmail.com> on 2011/10/20 14:41:22 UTC

VelocityMacro scope

Hi List,

it's been a while since I wrote here (at least a few years), mainly 
because I had not too much trouble resolving my issues myself but this 
time I am kind of stuck.
We recently upgraded from Velocity 1.6.2 to velocity 1.7 and we 
encountered a lot of issues. While I managed to fix most of them, there 
is an important one that I can't get passed.

Simplifying my code, here is a little snippet that used to work:
#macro(foo $bar)
     #set($bar = 100)
#end

#set($xyz = 0)
Before: $xyz
#foo($xyz)
After: $xyz

Basically, we pass a variable to a macro, and setting the value of the 
variable in the macro impacted the passed argument, ie, the output we 
used to have in 1.6.2 was:
Before: 0
After: 100
Now, in velocity 1.7, I get the following:
Before: 0
After: 0

This is of course a really strong change of behaviour but ok I guess 
there might be some good reason for that (although I think it kind of 
contradicts what the doc says about velcoity macro arguments since it 
says that the passed argument is re-evaluated each time it occurs in the 
VM, in my opinion, I feel that $bar should resolve to $xyz, and 
therefore the #set would set the value of $xyz. The whole point of doing 
that is to be able to return a value (or even several values) from a macro).

Now, the weirdest thing, I believe is, if you change the name of the 
passed argument to $bar:
#macro(foo $bar)
     #set($bar = 100)
#end

#set($bar= 0)
Before: $bar
#foo($bar)
After: $bar

Then I get what I used to have, ie:
Before: 0
After: 100

I feel like this is really mixing things up. Either the value can 
propagate from the macro to the calling-level, either it should be 
prevented. But have a mix of both of them is really not predictable nor 
robust. If by any chance, I happen to call my argument the same way it 
is called in the macro, the behaviour of the template is completely 
changed. I would assume that the name of a variable should not matter on 
both sides. I should be able to rename $bar to $bar123 without noticing 
any change and the same goes for $xyz which could be either $xyz or $bar 
without modifying the outcome. Or is this just me?
Personnally, I am in favour of the first behaviour.

Now, my question would be, how can I achieve the behaviour observed in 
1.6.2 with velocity 1.7, or what technique can I use to return values 
from a velocity macro?

If you wonder why I am trying to that instead of moving my code to Java 
classes, the reason is that I heavily rely on templates to generate all 
kinds of stuff (full web-application, Latex documents, DocX documents, 
etc...) but I also allow the user of my application to modify those 
templates at runtime without needing to know anything about classes, 
Java code, etc... I can get somebody started on VTL in 5 minutes while 
it would take me days to get him started with Java.

Thanks very much in advance,

Guillaume


---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@velocity.apache.org
For additional commands, e-mail: user-help@velocity.apache.org


Re: VelocityMacro scope

Posted by Guillaume Polet <gu...@gmail.com>.
Thanks Sergiu for your fast and perfect answer. It seems to me that we 
met the same kind of issues (I also had some issues with quotes escaping 
;-)). I even had issues with the '@' sign but that's another story.

Is there any way to get the previous behaviour with some kind of 
velocity property?
Is there an alternate suggested way of working, or am I forced to pass a 
map to push the returned values?

Thanks,

Guillaume

Le 20/10/2011 14:49, Sergiu Dumitriu a écrit :
> On 10/20/2011 08:41 AM, Guillaume Polet wrote:
>> Hi List,
>>
>> it's been a while since I wrote here (at least a few years), mainly
>> because I had not too much trouble resolving my issues myself but this
>> time I am kind of stuck.
>> We recently upgraded from Velocity 1.6.2 to velocity 1.7 and we
>> encountered a lot of issues. While I managed to fix most of them, there
>> is an important one that I can't get passed.
>>
>> Simplifying my code, here is a little snippet that used to work:
>> #macro(foo $bar)
>> #set($bar = 100)
>> #end
>>
>> #set($xyz = 0)
>> Before: $xyz
>> #foo($xyz)
>> After: $xyz
>>
>> Basically, we pass a variable to a macro, and setting the value of the
>> variable in the macro impacted the passed argument, ie, the output we
>> used to have in 1.6.2 was:
>> Before: 0
>> After: 100
>> Now, in velocity 1.7, I get the following:
>> Before: 0
>> After: 0
>>
>> This is of course a really strong change of behaviour but ok I guess
>> there might be some good reason for that (although I think it kind of
>> contradicts what the doc says about velcoity macro arguments since it
>> says that the passed argument is re-evaluated each time it occurs in the
>> VM, in my opinion, I feel that $bar should resolve to $xyz, and
>> therefore the #set would set the value of $xyz. The whole point of doing
>> that is to be able to return a value (or even several values) from a
>> macro).
>>
>> Now, the weirdest thing, I believe is, if you change the name of the
>> passed argument to $bar:
>> #macro(foo $bar)
>> #set($bar = 100)
>> #end
>>
>> #set($bar= 0)
>> Before: $bar
>> #foo($bar)
>> After: $bar
>>
>> Then I get what I used to have, ie:
>> Before: 0
>> After: 100
>>
>> I feel like this is really mixing things up. Either the value can
>> propagate from the macro to the calling-level, either it should be
>> prevented. But have a mix of both of them is really not predictable nor
>> robust. If by any chance, I happen to call my argument the same way it
>> is called in the macro, the behaviour of the template is completely
>> changed. I would assume that the name of a variable should not matter on
>> both sides. I should be able to rename $bar to $bar123 without noticing
>> any change and the same goes for $xyz which could be either $xyz or $bar
>> without modifying the outcome. Or is this just me?
>> Personnally, I am in favour of the first behaviour.
>>
>> Now, my question would be, how can I achieve the behaviour observed in
>> 1.6.2 with velocity 1.7, or what technique can I use to return values
>> from a velocity macro?
>>
>> If you wonder why I am trying to that instead of moving my code to Java
>> classes, the reason is that I heavily rely on templates to generate all
>> kinds of stuff (full web-application, Latex documents, DocX documents,
>> etc...) but I also allow the user of my application to modify those
>> templates at runtime without needing to know anything about classes,
>> Java code, etc... I can get somebody started on VTL in 5 minutes while
>> it would take me days to get him started with Java.
>>
>> Thanks very much in advance,
>
> See http://wiki.apache.org/velocity/MacroEvaluationStrategy and 
> http://www.xwiki.org/xwiki/bin/ReleaseNotes/ReleaseNotesXWikiEnterprise30#HMacroevaluationstrategy
>


---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@velocity.apache.org
For additional commands, e-mail: user-help@velocity.apache.org


Re: VelocityMacro scope

Posted by Guillaume Polet <gu...@gmail.com>.
One more remark regarding the macro evaluation strategy, especially 
after reading the article you mentionned below.
It states that the new behaviour is the following:

#macro(callBySharing $x $map)
   #set($x = 'a')
   $map.put('x', 'a')
#end
#set($y = 'y')
#set($map = {})
#callBySharing($y $map)
$y ->  'y' (but is 'a' in 1.6.2, 1.6.0 and before)
$map.x ->  'a'


But this is not completely true. The following example contradicts that 
statement:

#macro(callBySharing $x $map)
   #set($x = 'a')
   $map.put('x', 'a')
#end
*#set($x = 'x')*
#set($map = {})
#callBySharing($y $map)
*$x ->  'a' (and is also 'a' in 1.6.2, 1.6.0 and before)*
$map.x ->  'a'

Isn't this even more counter-intuitive? Is this expected or is it a 
known bug?

Cheers,
Guillaume


Le 20/10/2011 14:49, Sergiu Dumitriu a écrit :
> On 10/20/2011 08:41 AM, Guillaume Polet wrote:
>> Hi List,
>>
>> it's been a while since I wrote here (at least a few years), mainly
>> because I had not too much trouble resolving my issues myself but this
>> time I am kind of stuck.
>> We recently upgraded from Velocity 1.6.2 to velocity 1.7 and we
>> encountered a lot of issues. While I managed to fix most of them, there
>> is an important one that I can't get passed.
>>
>> Simplifying my code, here is a little snippet that used to work:
>> #macro(foo $bar)
>> #set($bar = 100)
>> #end
>>
>> #set($xyz = 0)
>> Before: $xyz
>> #foo($xyz)
>> After: $xyz
>>
>> Basically, we pass a variable to a macro, and setting the value of the
>> variable in the macro impacted the passed argument, ie, the output we
>> used to have in 1.6.2 was:
>> Before: 0
>> After: 100
>> Now, in velocity 1.7, I get the following:
>> Before: 0
>> After: 0
>>
>> This is of course a really strong change of behaviour but ok I guess
>> there might be some good reason for that (although I think it kind of
>> contradicts what the doc says about velcoity macro arguments since it
>> says that the passed argument is re-evaluated each time it occurs in the
>> VM, in my opinion, I feel that $bar should resolve to $xyz, and
>> therefore the #set would set the value of $xyz. The whole point of doing
>> that is to be able to return a value (or even several values) from a
>> macro).
>>
>> Now, the weirdest thing, I believe is, if you change the name of the
>> passed argument to $bar:
>> #macro(foo $bar)
>> #set($bar = 100)
>> #end
>>
>> #set($bar= 0)
>> Before: $bar
>> #foo($bar)
>> After: $bar
>>
>> Then I get what I used to have, ie:
>> Before: 0
>> After: 100
>>
>> I feel like this is really mixing things up. Either the value can
>> propagate from the macro to the calling-level, either it should be
>> prevented. But have a mix of both of them is really not predictable nor
>> robust. If by any chance, I happen to call my argument the same way it
>> is called in the macro, the behaviour of the template is completely
>> changed. I would assume that the name of a variable should not matter on
>> both sides. I should be able to rename $bar to $bar123 without noticing
>> any change and the same goes for $xyz which could be either $xyz or $bar
>> without modifying the outcome. Or is this just me?
>> Personnally, I am in favour of the first behaviour.
>>
>> Now, my question would be, how can I achieve the behaviour observed in
>> 1.6.2 with velocity 1.7, or what technique can I use to return values
>> from a velocity macro?
>>
>> If you wonder why I am trying to that instead of moving my code to Java
>> classes, the reason is that I heavily rely on templates to generate all
>> kinds of stuff (full web-application, Latex documents, DocX documents,
>> etc...) but I also allow the user of my application to modify those
>> templates at runtime without needing to know anything about classes,
>> Java code, etc... I can get somebody started on VTL in 5 minutes while
>> it would take me days to get him started with Java.
>>
>> Thanks very much in advance,
>
> See http://wiki.apache.org/velocity/MacroEvaluationStrategy and 
> http://www.xwiki.org/xwiki/bin/ReleaseNotes/ReleaseNotesXWikiEnterprise30#HMacroevaluationstrategy
>


Re: VelocityMacro scope

Posted by Sergiu Dumitriu <se...@xwiki.com>.
On 10/20/2011 08:41 AM, Guillaume Polet wrote:
> Hi List,
>
> it's been a while since I wrote here (at least a few years), mainly
> because I had not too much trouble resolving my issues myself but this
> time I am kind of stuck.
> We recently upgraded from Velocity 1.6.2 to velocity 1.7 and we
> encountered a lot of issues. While I managed to fix most of them, there
> is an important one that I can't get passed.
>
> Simplifying my code, here is a little snippet that used to work:
> #macro(foo $bar)
> #set($bar = 100)
> #end
>
> #set($xyz = 0)
> Before: $xyz
> #foo($xyz)
> After: $xyz
>
> Basically, we pass a variable to a macro, and setting the value of the
> variable in the macro impacted the passed argument, ie, the output we
> used to have in 1.6.2 was:
> Before: 0
> After: 100
> Now, in velocity 1.7, I get the following:
> Before: 0
> After: 0
>
> This is of course a really strong change of behaviour but ok I guess
> there might be some good reason for that (although I think it kind of
> contradicts what the doc says about velcoity macro arguments since it
> says that the passed argument is re-evaluated each time it occurs in the
> VM, in my opinion, I feel that $bar should resolve to $xyz, and
> therefore the #set would set the value of $xyz. The whole point of doing
> that is to be able to return a value (or even several values) from a
> macro).
>
> Now, the weirdest thing, I believe is, if you change the name of the
> passed argument to $bar:
> #macro(foo $bar)
> #set($bar = 100)
> #end
>
> #set($bar= 0)
> Before: $bar
> #foo($bar)
> After: $bar
>
> Then I get what I used to have, ie:
> Before: 0
> After: 100
>
> I feel like this is really mixing things up. Either the value can
> propagate from the macro to the calling-level, either it should be
> prevented. But have a mix of both of them is really not predictable nor
> robust. If by any chance, I happen to call my argument the same way it
> is called in the macro, the behaviour of the template is completely
> changed. I would assume that the name of a variable should not matter on
> both sides. I should be able to rename $bar to $bar123 without noticing
> any change and the same goes for $xyz which could be either $xyz or $bar
> without modifying the outcome. Or is this just me?
> Personnally, I am in favour of the first behaviour.
>
> Now, my question would be, how can I achieve the behaviour observed in
> 1.6.2 with velocity 1.7, or what technique can I use to return values
> from a velocity macro?
>
> If you wonder why I am trying to that instead of moving my code to Java
> classes, the reason is that I heavily rely on templates to generate all
> kinds of stuff (full web-application, Latex documents, DocX documents,
> etc...) but I also allow the user of my application to modify those
> templates at runtime without needing to know anything about classes,
> Java code, etc... I can get somebody started on VTL in 5 minutes while
> it would take me days to get him started with Java.
>
> Thanks very much in advance,

See http://wiki.apache.org/velocity/MacroEvaluationStrategy and 
http://www.xwiki.org/xwiki/bin/ReleaseNotes/ReleaseNotesXWikiEnterprise30#HMacroevaluationstrategy

-- 
Sergiu Dumitriu
http://purl.org/net/sergiu/

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@velocity.apache.org
For additional commands, e-mail: user-help@velocity.apache.org