Re: "While"-like structure in Velocity?
Sergiu Dumitriu <[email protected]>
| Newsgroups | gmane.comp.jakarta.velocity.user |
|---|---|
| Message-ID | <[email protected]> |
On 05/16/2013 11:23 AM, Christopher Schultz wrote:
> Sergiu,
>
> On 5/15/13 3:04 PM, Sergiu Dumitriu wrote:
>> On 05/15/2013 12:11 PM, Christopher Schultz wrote:
>>> All,
>>>
>>> I've searched the archives for "while" capabilities in Velocity, and
>>> mostly the answers have been things like "that's beyond the scope of
>>> Velocity... you want a real programming language for that".
>>>
>>> I'd like to do something that naturally would use a while loop, but
>>> perhaps someone can offer an alternative suggestion.
>>>
>>> I need to traverse a queue, but that queue needs to be able to modify
>>> itself during the processing. Basically, something like this:
>>>
>>> while (!queue.empty) {
>>> // do something with the head element
>>> // possible enqueue some more items at the back
>>> }
>>>
>>> #foreach would be the way to do it if the queue didn't have to be
>>> modified, but I'll get an exception if I try to traverse an iterator
>>> over the queue and then modify it mid-flight.
>>>
>>> Right now, I have this written as a JSP but I'd rather have it as a
>>> Velocity template.
>>>
>>> My only thought is to create an ugly class that implements Iterator and
>>> wraps the queue but is much less strict than a standard iterator. Any
>>> suggestions?
>>>
>>> -chris
>>>
>>
>> While not a very clean solution, you can use a very large foreach and
>> manually work with the queue inside the loop, and #break($foreach) once
>> the queue is empty:
>>
>> #foreach($i in [0..100000])
>> #if ($queue.isEmpty())
>> #break($foreach)
>> #end
>> #set ($item = $queue.pop())
>> ## Do stuff with $item
>> #if (should add more things)
>> #set ($discard = $queue.add(new things))
>> #end
>> #end
>
> That's actually a great suggestion. I've never used "break" in a foreach
> loop before. $foreach becomes the loop-control identifier for #break?
$foreach is an automatically defined scope variable, it is more than
just a target for #break.
http://velocity.apache.org/engine/devel/velocity-engine-core/apidocs/org/apache/velocity/runtime/directive/ForeachScope.html
http://velocity.apache.org/engine/releases/velocity-1.7/user-guide.html#Break
has more information about the optional scope you can pass to #break.
Actually it's not needed to pass $foreach to it if it is the innermost
scope, but it is useful for example if you want to break out of nested
scopes, like:
#break($foreach.parent)
#break($foreach.topmost)
> I'll give that a try. 10,000 seems completely reasonable given that (for
> now) I'll never really have a queue that grows to a size more than about
> 5000, even in the most pathological case.
--
Sergiu Dumitriu
http://purl.org/net/sergiu