On Tue, May 1, 2012 at 7:59 AM, Boris Partensky <boris.parten...@gmail.com> wrote: >> Yes, compatibility was and is a goal, but with limited resources, >> continuing support for implicit scoping in macros didn't make the cut. > > Ok. Are there any BC corner cases other than nested macros I should be > aware of? I could not really find the No-BC notification you had > mentioned.
Hmm. I think the #evaluate directive also lost its implicit scope, but i'd have to double check on that. >>> * When scopes of the same type are nested make the parent Scope >>> available through the child (e.g. $foreach.parent or >>> $foreach.topmost). > > Thanks. So, with macro.provide.scope.control =true scoping behavior > should stay the same, and I'd have to explicitly use scope handles to > reach different scopes, like $mymacroname.parent for example, or > $macro.parent. Is this correct? Yep. Explicit read/write is the name of the game. And just to make sure we're on the same page, $mymacroname scope control would only be provided when using #macro( mymacroname ) as a macro with a body (#@mymacroname() $mymacroname #end) and you set mymacroname.provide.scope.control = true and $mymacroname.parent would only exist if you are nesting calls to #@mymacroname :) > Thanks > Boris > > > > On Mon, Apr 30, 2012 at 5:08 PM, Nathan Bubna <nbu...@gmail.com> wrote: >> On Mon, Apr 30, 2012 at 1:06 PM, Boris Partensky >> <boris.parten...@gmail.com> wrote: >>> I am seeing 3 bullet points there pertinent to this issue and all 3 >>> seem to indicate that being compatible was the intention there, or am >>> I wrong ? The way I read #2 and #3 is that the parent scope should >>> only be available if I explicitly specify the scope I want (parent or >>> topmost or replaced). >> >> Yes, compatibility was and is a goal, but with limited resources, >> continuing support for implicit scoping in macros didn't make the cut. >> >>> * For performance and compatibility these are all off by default, >>> *except* for $foreach. The others may be enabled by setting a velocity >>> property like:macro.provide.scope.control = true >> >> "off for compatibility" here means reduced chance of squashing >> someone's previous $macro or $template var, or more realistically $foo >> when there is a body macro call #foo >> >>> * When scopes of the same type are nested make the parent Scope >>> available through the child (e.g. $foreach.parent or >>> $foreach.topmost). >> >> $<scope>.parent is always and only made available when there actually >> is an explicit parent scope provided. e.g. >> >> #foreach( $a in $b ) >> #foreach( $c in $d ) >> $foreach.parent here == $foreach.topmost >> #end >> $foreach here == $foreach.topmost >> #end >> >> Think parent and topmost as ways to navigate the scope stack, which >> only exists when <scope>.provide.scope.control = true >> >>> * When a Scope reference overrides an existing reference that is not a >>> Scope, make it available through the Scope (e.g. $foreach.replaced). >> >> $<scope>.replaced is not a parent scope, but is 'bar' in the example: >> #set($foo='bar') #@foo $foo.replaced #end >> >> This is a workaround for incompatibilities/migrations/etc. It doesn't >> provide any compatibility with the older implicit system of scoping. >> >>> On Mon, Apr 30, 2012 at 3:51 PM, Nathan Bubna <nbu...@gmail.com> wrote: >>>> http://velocity.apache.org/engine/devel/changes-report.html#a1.7 >>>> >>>> On Mon, Apr 30, 2012 at 12:37 PM, Boris Partensky >>>> <boris.parten...@gmail.com> wrote: >>>>> No problem, thanks for making things clear. >>>>> >>>>> << we decided to forego it and notify users of the non-BC change when >>>>> we released 1.7. >>>>> >>>>> which notification are you referring to? Wonder if there is something >>>>> else in there I am not aware of. >>>>> >>>>> >>>>> On Mon, Apr 30, 2012 at 2:34 PM, Nathan Bubna <nbu...@gmail.com> wrote: >>>>>> Congratulations, Boris. You are the corner case we feared. :-/ We >>>>>> knew when we went ahead with this that providing a migration path >>>>>> would be difficult. We knew most users didn't have extreme numbers of >>>>>> macros and hoped that those who didn't frequently nest them, in part >>>>>> because of the complexities of heavy scoping in a language that often >>>>>> treated scoping as a second-class feature, and in part because of the >>>>>> performance issues macros had prior to 1.6. #parse, >>>>>> VelocityLayoutServlet and even custom tools, which lack the implicit >>>>>> scoping support, tended to be more performant and encouraged for >>>>>> simplifying complicated tools. Considering those things and the >>>>>> difficulty of implementing a BC switch for implicit scoping, we >>>>>> decided to forego it and notify users of the non-BC change when we >>>>>> released 1.7. >>>>>> >>>>>> Sorry. It sounds like it's going to take some legwork to upgrade in >>>>>> the cases where you nested your macros. >>>>>> >>>>>> On Mon, Apr 30, 2012 at 11:16 AM, Boris Partensky >>>>>> <boris.parten...@gmail.com> wrote: >>>>>>> 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 >>>>>>> >>>>>> >>>>>> --------------------------------------------------------------------- >>>>>> 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 >> > > --------------------------------------------------------------------- > 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