Yeah, it was intended, and part of an overall move toward fixing/simplifying Velocity's variable scoping, avoiding the complexities and costs (performance, yes, but mostly time/brainpower for users and devs alike) of more programming language type behavior. Velocity has long aspired to be a straightfoward template engine and avoid being a complete scripting language. (Implicit) variable scoping, as seen in 1.5, was seen as a necessary compromise toward the latter; after all, one big fat namespace is always unmanageable, right? Well, there's ways to make that easy to manage. :) Let's call it "optional, provided, explicit scoping", explicit because you don't have to grok the contextual scope to understand a reference, optional because you can ignore it, and provided because Velocity does the work of choosing "prefixes" and creating/destroying the scopes (as any implicit scoping system does). So everything is becoming globally scoped, but it is now trivial to turn on automatic, explicit scopes or namespaces that you can use when you don't want things to live in the global scope.
Here's an example... Do you use $velocityCount to get an index of sorts inside of #foreach directives? Well, that's an example of mixed implicit/explicit namespacing that gets messy when you nest #foreach's, with no good way to get the parent's count and unwieldiness when you want to add $velocityIndex, $velocityHasNext and so on. Now, we automatically manage a $foreach var that not only has a 'count' property, but an 'index', 'hasNext', 'parent', and so on (see http://velocity.apache.org/engine/devel/apidocs/org/apache/velocity/runtime/directive/ForeachScope.html). It also, of course, accepts any property you want to set on it (like any map). This makes templates instantly understandable, making debugging much better. You always know exactly what you are referring to, and so does anyone else reading the template. #foreach is the only 'content directive' that has its explicit scope automatically turned on, but all content containing directives (including custom body macros) can have their own explicit, auto-managed scope, named after themselves. for example, you can flip the macro scope on: macro.provide.scope.control = true and do: #macro( outer $arg ) #set( $macro.arg = $arg ) #inner( 'inner' ) #end #macro( inner $arg ) #set( $macro.arg = $arg) inner: $macro.arg #if( $macro.parent )outer: $macro.parent.arg#end #end #outer( 'outer' ) #inner( 'just inner' ) and get inner: inner outer: outer inner: just inner Hope this helps... In any case, there was plenty of thought and discussion that went into this change. Search http://velocity.markmail.org for 'scope' and you should find more on this. On Mon, Apr 30, 2012 at 8:49 AM, Boris Partensky <boris.parten...@gmail.com> wrote: > Hello, while going through the upgrade I noticed an incompatible > behavior during nested macro evaluation. Looks like in 1.7 (all > default properties) child macro has access to variables set in parent > macro scope (and those take precedence over globals), and 1.5 sees > globals. In the following example, in 1.5 unit test the following > template will evaluate to "globalvar", and in 1.7 - to > "outermacroparam". Is this expected behavior? > > > 1.5 test case > > > public void testVelocityNestedMacroScope() throws Exception > { > VelocityEngine ve = new VelocityEngine(); > > ve.init(); > > String template = "#macro(outerMacro $arg1)"+ > "#innerMacro('blah')"+ > "#end"+ > "#macro(innerMacro $arg2)$arg1#end"+ > > "#set($arg1='globalval')#outerMacro('outermacroparam')"; > StringWriter eval = new StringWriter(); > boolean b = ve.evaluate(new VelocityContext(), eval, "foo", template); > assertEquals(eval.toString(), "globalval", eval.toString()); > > } > > 1.7 test case > > > public void testVelocityNestedMacroScope() > { > String template = "#macro(outerMacro $arg1)"+ > "#innerMacro('blah')"+ > "#end"+ > "#macro(innerMacro $arg2)$arg1#end"+ > > "#set($arg1='globalvar')#outerMacro('outermacroparam')"; > String eval = evaluate(template); > assertEquals(eval, "outermacroparam", eval); > > } > > --------------------------------------------------------------------- > To unsubscribe, e-mail: user-unsubscr...@velocity.apache.org > For additional commands, e-mail: user-h...@velocity.apache.org > --------------------------------------------------------------------- To unsubscribe, e-mail: user-unsubscr...@velocity.apache.org For additional commands, e-mail: user-h...@velocity.apache.org