This proposal does not solve the use case provided. I also had several cases where I wanted the numbering to be consistent across several forEach calls and also had to implement hacks.BURGHARD Éric wrote:
I'm working on refactoring JXTG so that it will be easier to support and develop. I'm aware about that you have access the request object etc
Great ! Don't know if i can help (time), but if you have a road map or something like that, i would be happy to contribute.
I will write a roadmap. All contributions are welcome, a simple but important contribution is to start using the refactored JXTG instead of the original and report or even better send patches for the bugs.
differently depending on if you are using flow or not and also that the eval tag is less well designed. What more weird behaviours are you thinking of?
Variable nature and scope (kind of non-mutable that you can overwrite ?),
but someone could tell me this a feature :-). Perhaps i've miss something,
but look what i need to do to retrieve a value incremented inside a forEach
loop:
<jx:set var="globalvars" value="${java.util.HashMap(5)}"/> <jx:set var="dummy" value="${globalvars.put('a_count', 0)}"/> ... <jx:set var="a_count" value="${globalvars.a_count}"/> <jx:forEach begin="1" end="3" varStatus="i"> ... <jx:if test="#{$node/@path != ''}"> ... <jx:set var="a_count" value="${a_count+1}"/> <jx:set var="dummy" value="${globalvars.put('a_count', a_count)}"/> </jx:if> </jx:forEach>
<jx:out>this is my count: ${globalvars.a_count}</jx:out>
It would be easiest (and efficient) to do <jx:set var="a_count" value="0"/> <jx:forEach begin="1" end="3" varStatus="i"> ... <jx:if test="#{$node/@path != ''}"> ... <jx:set var="a_count" value="${a_count+1}"/> </jx:forEach>
<jx:out>this is my count: ${a_count}</jx:out>
the fact that "set" make always a "new define" is quite annoying at first glance (functional programming ?).
The expression context is implemented as a stack of maps and the put instruction on the context is a put on the top map. ForEach is implemented in such way that the loop is performed in a local map that is pushed on stack before the loop and poped afterwards. The set instruction will do a put on the top map and will disapear afterwards because of that.
Ok, that explains the behaviour, the question is what we should do about the, admitingly, weird behaviour.
One possibilty would be to decide that we want JXTG to be more like a functional language. In that case we should deprecate jx:set and introduce a jx:let instead that just gives a local name for an expression and that gives an exception if you try to set the "variable" to a new value. I think I would prefer this behaviour as I would prefer having a template language without side effects.
I prefer the second solution. The only thing to make the use case work is the ability to set the variable without implicit declaration.
Another possibility is to let set asign the value to the first variable binding with the same name that it finds when the stack is searched, instead of creating a new binding at the top of the stack if the name doesn't exist on the top of the stack. If we go for this we need two constructions one that declare and possibly gives an intial value to a variable in the current context and one that binds the uppermost occurance of the name, a jx:declare and a jx:set e.g.
Also we would need to change the API and behaviour of ExpressionContext so that we both have a declare and a set method. This should probably be done anyway.
WDYT?
/Daniel
One more question: should jx:set automatically declare if there is no previous declaration? I think yes.
When we reach an agreement I can implement it as it looks quite straightforward.
-- Leszek Gawron [EMAIL PROTECTED] Project Manager MobileBox sp. z o.o. +48 (61) 855 06 67 http://www.mobilebox.pl mobile: +48 (501) 720 812 fax: +48 (61) 853 29 65