You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@velocity.apache.org by "Nathan Bubna (JIRA)" <de...@velocity.apache.org> on 2010/04/07 18:49:34 UTC
[jira] Resolved: (VELTOOLS-124) LoopTool fails to retrieve
$loop.index, $loop.first etc for the last element in a collection.
[ https://issues.apache.org/jira/browse/VELTOOLS-124?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Nathan Bubna resolved VELTOOLS-124.
-----------------------------------
Resolution: Fixed
Fix Version/s: 2.0
Unfortunately, there is no alternative time to pop the last iterator from the stack. There is no way to have the #foreach directive notify the LoopTool that #end was reached. It's just not possible without hacking Velocity Engine itself.
However, Velocity 1.7 will soon have a beta release and hopefully a final release shortly thereafter. With that release is the advent of the $foreach "control" object. That will provide $foreach.count $foreach.index $foreach.last $foreach.first and $foreach.hasNext to all #foreach loops. It will also provide access to $foreach.parent and $foreach.parent.parent and so on up to $foreach.topmost to provide access to all those properties in nested situations. Oh, and the #break directive is upgraded to accept a #break( $foreach.parent ) argument and so on.
All that is to say that the LoopTool will soon be only useful for the sync, skip and stop condition features, which are not affected by this bug.
Still, in the short term, i've got a solution for those wishing to always have accurate index, count, etc properties. I've provided access to the underlying ManagedIterator wrapper:
#foreach( $i in $loop.watch([1..3]) )
#set( $this = $loop.this )
i[$this.index]=$i;
#end
The $loop.this reference will always provide the ManagedIterator from the most recent $loop.watch() call. Along with this, i have actually "fixed" this specific bug in some situations by using that "last" iterator reference. So, in simple situations like the example you gave, things should work fine. However, in nested loop situations, things get messy once you start getting beyond the first #end on the final iteration(s) of the nested #foreach calls. Your only reliable bet in that situation is to grab the $loop.this reference at the top of each #foreach and use those to get what you need or to otherwise not reference $loop properties directly after the first #end.
Though, again, for index/count/first/last/hasNext properties, the only proper solution is the upcoming $foreach reference in Velocity 1.7. Once $foreach is well established, those properties of $loop should probably just be removed.
> LoopTool fails to retrieve $loop.index, $loop.first etc for the last element in a collection.
> ---------------------------------------------------------------------------------------------
>
> Key: VELTOOLS-124
> URL: https://issues.apache.org/jira/browse/VELTOOLS-124
> Project: Velocity Tools
> Issue Type: Bug
> Components: GenericTools
> Affects Versions: 2.x
> Environment: velocity-tools-2.0-beta4 with velocity-1.6.2
> Reporter: Sergiy Kovalchuk
> Fix For: 2.0, 2.x
>
>
> $loop.index, $loop.first and other LoopTool methods (that depend on iterator) return null for the last element in a collection.
> Try to run:
> #set( $list = [1..3] )
> #foreach($i in $loop.watch($list))
> i[${loop.index}]=$i;
> #end
> The result is:
> i[0]=1; i[1]=2; i[${loop.index}]=3;
> I tried to investigate it a little, and seems like the problem is inside "cacheNext(boolean popWhenDone)".
> First it checks if (!iterator.hasNext()) and if not then removes this iterator from the stack. But later in this method it retrieves next element from a collection "this.next = iterator.next();". Seems like it causes removing iterator too early, when calling ${loop.index} on the last element the iterator is already removed.
> Thanks.
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@velocity.apache.org
For additional commands, e-mail: dev-help@velocity.apache.org