Yep, I am afraid we do set globals from within macros... On Mon, Apr 30, 2012 at 2:05 PM, Nathan Bubna <nbu...@gmail.com> wrote: > Can you set velocimacro.context.localscope = true or is it important > for your system to be able to #set global stuff from within macros? > > On Mon, Apr 30, 2012 at 10:50 AM, Boris Partensky > <boris.parten...@gmail.com> wrote: >> Thanks Nathan, I think I do get the whole scoping idea, but my >> understanding was that one of the reasons to turn all scoping off by >> default (and have those properties to begin with) was to provide >> backward compatibility - as in: I upgrade to 1.7 and then I start >> turning on all those nice bells and whistles and use scopes and what >> not. Not so seems like? I also find somewhat strange that a a formal >> argument to a macro takes precedence and overwrites a global variable >> with the same name. How would one go about upgrading existing systems? >> We have roughly 1900 macros, big chunk of those are nested... Maybe I >> am misunderstanding something, but this issue makes it almost >> impossible to upgrade (at least for us). >> >> >> Thanks >> Boris >> >> On Mon, Apr 30, 2012 at 12:55 PM, Nathan Bubna <nbu...@gmail.com> wrote: >>> 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 >>> >> >> --------------------------------------------------------------------- >> 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 >
--------------------------------------------------------------------- To unsubscribe, e-mail: user-unsubscr...@velocity.apache.org For additional commands, e-mail: user-h...@velocity.apache.org