Re: Unexpected variable scoping rules if #include is used within a #macro
Daniel Dekany <[email protected]>
| Newsgroups | gmane.comp.web.freemarker.user |
|---|---|
| Message-ID | <[email protected]> |
Saturday, May 2, 2009, 11:27:36 AM, Attila Szegedi wrote:
> Sounds like [#embed] from 2.4 would do what John expects it would - do
> you agree Daniel?
I don't think so... He rather wanted something like #include + #var,
since he wants all the variables that are visible at the place of
#include to be visible inside the included template, yet he don't want
the variables created in the included template to have any effect on
the variable set of the including template. Anyway, I think that's
quite a bad idea in most applications, exposing local variables to
another template... and *maybe* John's application is not an exception
either. (In several such cases it will certainly turn out that
exposing the variables of the including place wasn't that important
thing originally, the intent was rather that the developer wants many
smaller files (and hence possibly leveraging some template-loading
facilities, like "acquisition") instead of a few big macro libraries.)
> Maybe we could implement it for 2.3 as well (not sure how much of the
> underlying 2.4 machinery would need to be ported though, so it might
> not be worth the effort).
I'm not even sure 2.4 worth the effort... or better said, if it's the
right place to invest our energies into. We have a significant 2.3.x
user-base. You think they will suffer with migrating ti 2.4.x? Not
many of them, I think. People will rather just start using 2.4 in new
projects. But then, well... while we have this visibility as we have
now, shouldn't give them something that indeed fixes the several
issues with the overall architecture? That will be unpopular in short
term, but I'm certain not on the long term...
> Attila.
>
> On 2009.05.01., at 23:50, Daniel Dekany wrote:
>
>> Friday, May 1, 2009, 10:46:33 PM, Newman, John W wrote:
>>> Hello,
>>>
>>> We are using FM 2.3, and we’ve spotted a strange bug with our code.
>>> I’ve been wading through the docs for a bit here but haven’t found
>>> the answer as to why this is happening. Perhaps a simple test is
>>> the best way to explain it:
>>>
>>> Main template:
>>> [#ftl]
>>> [#import "scopeTest.ftl" as test /]
>>> [@test.runTest /]
>>>
>>> scopeTest.ftl:
>>> [#ftl]
>>> [#macro runTest]
>>> [#list 1..30 as i]
>>> [#include "strangeScope.ftl" /]
>>> [/#list]
>>> [/#macro]
>>>
>>> strangeScope.ftl:
>>> [#ftl]
>>> [#if i % 10 == 0]
>>> [#assign someLocal = i + 2 /]
>>> [/#if]
>>> ${i} ${someLocal!'not defined'}<br />
>>>
>>> Produces this output:
>>>
>>> 1 not defined
>>> 2 not defined
>>> 3 not defined
>>> 4 not defined
>>> 5 not defined
>>> 6 not defined
>>> 7 not defined
>>> 8 not defined
>>> 9 not defined
>>> 10 12
>>> 11 12 < What?
>>> 12 12 < Why is this still here
>>> 13 12 < shouldn’t it say not defined, since, once the include
>>> reaches EOF the someLocal is out of scope and destroyed?
>>> 14 12
>>> 15 12
>>> 16 12
>>> 17 12
>>> 18 12
>>> 19 12
>>> 20 22 < correct
>>> 21 22 < this should say undefined??
>>> 22 22
>>> 23 22
>>> 24 22
>>> 25 22
>>> 26 22
>>> 27 22
>>> 28 22
>>> 29 22
>>> 30 32
>>>
>>> Is this expected behavior?
>>
>> Yes... frankly, I don't quite get what's odd about it.
>>
>>> Why does a variable that is not declared in a macro remain in scope
>>> for the entire macro?
>>
>> [#include ] has copy-paste-like semantic regarding variable scoping.
>> It's a bit like #include in C, you see. Also, #assign creates the
>> variable on the top-level, which is yet another reason it won't go out
>> of scope. BTW, the variable scoping rules are described here:
>> http://freemarker.org/docs/dgui_misc_var.html
>>
>>> [#local sounds like what I want but that is not permitted in the
>>> include.
>>
>> That indeed won't work there since the included file is parsed without
>> assuming that it will be used inside a macro (and that indeed can't be
>> find that out), and #local works only inside #macro or #function. But
>> even if #local worked there the output would be the same, as the
>> #local variable is created in the scope of the nearest enclosing
>> #macro/#function.
>>
>>> If the someLocal var was declared within the macro itself this is
>>> what I would expect, however in this case, I’m expecting it to be
>>> declared, destroyed, re-declared within the include. The macro
>>> shouldn’t even know it is there. Right?
>>
>> Well, #assign creates kind of global variables. Well, it's not
>> absolutely global (that's why we also have #global) if you look into
>> the topic of #import-s... but it doesn't mater now. What you have
>> expected is maybe rather like #var in FreeMarker 2.4
>> (http://freemarker.org/docs-24pre1/dgui_misc_var.html), which is not
>> released yet (and it won't be in the foreseeable future).
>>
>>> Is this a bug or a feature? If it’s the latter, please explain the
>>> reasoning here and what the best practice is if any.
>>
>> Code snippets that meant to be black-boxes are usually implemented as
>> macros. They can also have parameters and nested content, which is a
>> huge advantage over includes.
>>
>>> Is it more correct to ditch the include, convert it to a second
>>> macro and use local?
>>
>> I guess... without seeing the concrete application of course.
>>
>>> I’m a bit confused on this and concerned that we could have several
>>> other instances of include within macro…
>>
>> I don't think the behavior of #include is surprising regarding
>> variables, as this how "include" works in most languages that has it.
>> Also the documentation
>> (http://freemarker.org/docs/ref_directive_include.html) says: "The
>> included file shares the variables with the including template,
>> similarly like if it was copy-pased into it."
>>
>>> Thanks as always.
>>
>> --
>> Best regards,
>> Daniel Dekany
>
> ------------------------------------------------------------------------------
> Register Now & Save for Velocity, the Web Performance & Operations
> Conference from O'Reilly Media. Velocity features a full day of
> expert-led, hands-on workshops and two days of sessions from industry
> leaders in dedicated Performance & Operations tracks. Use code vel09scf
> and Save an extra 15% before 5/3. http://p.sf.net/sfu/velocityconf
> _______________________________________________
> FreeMarker-user mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/freemarker-user
>
--
Best regards,
Daniel Dekany
------------------------------------------------------------------------------
Register Now & Save for Velocity, the Web Performance & Operations
Conference from O'Reilly Media. Velocity features a full day of
expert-led, hands-on workshops and two days of sessions from industry
leaders in dedicated Performance & Operations tracks. Use code vel09scf
and Save an extra 15% before 5/3. http://p.sf.net/sfu/velocityconf
_______________________________________________
FreeMarker-user mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/freemarker-user