> 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.

>> * 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?

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

Reply via email to