velocity-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Nathan Bubna <nbu...@gmail.com>
Subject Re: upgrading from 1.5 to 1.7 compatibility issues
Date Tue, 01 May 2012 15:55:09 GMT
On Tue, May 1, 2012 at 7:59 AM, Boris Partensky
<boris.partensky@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 <nbubna@gmail.com> wrote:
>> On Mon, Apr 30, 2012 at 1:06 PM, Boris Partensky
>> <boris.partensky@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 <nbubna@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.partensky@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 <nbubna@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.partensky@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 <nbubna@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.partensky@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 <nbubna@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.partensky@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-unsubscribe@velocity.apache.org
>>>>>>>>>>> For additional commands, e-mail: user-help@velocity.apache.org
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> ---------------------------------------------------------------------
>>>>>>>>>> To unsubscribe, e-mail: user-unsubscribe@velocity.apache.org
>>>>>>>>>> For additional commands, e-mail: user-help@velocity.apache.org
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>> ---------------------------------------------------------------------
>>>>>>>>> To unsubscribe, e-mail: user-unsubscribe@velocity.apache.org
>>>>>>>>> For additional commands, e-mail: user-help@velocity.apache.org
>>>>>>>>>
>>>>>>>>
>>>>>>>> ---------------------------------------------------------------------
>>>>>>>> To unsubscribe, e-mail: user-unsubscribe@velocity.apache.org
>>>>>>>> For additional commands, e-mail: user-help@velocity.apache.org
>>>>>>>>
>>>>>>>
>>>>>>> ---------------------------------------------------------------------
>>>>>>> To unsubscribe, e-mail: user-unsubscribe@velocity.apache.org
>>>>>>> For additional commands, e-mail: user-help@velocity.apache.org
>>>>>>>
>>>>>>
>>>>>> ---------------------------------------------------------------------
>>>>>> To unsubscribe, e-mail: user-unsubscribe@velocity.apache.org
>>>>>> For additional commands, e-mail: user-help@velocity.apache.org
>>>>>>
>>>>>
>>>>> ---------------------------------------------------------------------
>>>>> To unsubscribe, e-mail: user-unsubscribe@velocity.apache.org
>>>>> For additional commands, e-mail: user-help@velocity.apache.org
>>>>>
>>>>
>>>> ---------------------------------------------------------------------
>>>> To unsubscribe, e-mail: user-unsubscribe@velocity.apache.org
>>>> For additional commands, e-mail: user-help@velocity.apache.org
>>>>
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: user-unsubscribe@velocity.apache.org
>>> For additional commands, e-mail: user-help@velocity.apache.org
>>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: user-unsubscribe@velocity.apache.org
>> For additional commands, e-mail: user-help@velocity.apache.org
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@velocity.apache.org
> For additional commands, e-mail: user-help@velocity.apache.org
>

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


Mime
View raw message