Re: "While"-like structure in Velocity?
Christopher Schultz <[email protected]>
| Newsgroups | gmane.comp.jakarta.velocity.user |
|---|---|
| Message-ID | <[email protected]> |
Sergiu,
On 5/16/13 11:37 AM, Sergiu Dumitriu wrote:
> 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.
Works great all-around. Thanks for the suggestion.
-chris
signature.asc
(application/pgp-signature, 946 B)
-----BEGIN PGP SIGNATURE----- Version: GnuPG/MacGPG2 v2.0.17 (Darwin) Comment: GPGTools - http://gpgtools.org Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/ iQIcBAEBCAAGBQJRlRToAAoJEBzwKT+lPKRYiBkP/2OfjCijfCUp6lAIyrnlMcey 6ajXyt7yaR+iS2TDZd2xzaPgRoLZ4REm6C6bFUH2t+xEPQD+2IB/PExhwG7virgS DTaMmVlSTLam76UlT19kcAgZvcNxxpbD4YuTwcd4d5/3cpCAE6NRu+s+YbZOVEjw bryMM27Y6gJ8GsDI1NPhPFgJKOLLp/nPfsncukiK2T8BIKVkXZFiJTvomTCdZzyT qthpGFRYgLA9tQSx1+6ZCnKiWArk8fz8MySoD1DM64Asl6fBs42g0g97gnXetdiZ zuodC1KMfegaxUiIsmz7UnA9BSPUKB4vueNW3LFeGyj3s7hyxLNBMXFR+FG8v+Yc rrpfPzfjmam8+n0raZGIoU4HkKAYlXsupejuwmPmgg2k1enXTwEn8izW5UaF6DgF HnBUqum16NDKuu9wCM5vf19mz80Tpd/TqoBd2sOILjSG/2ggT2AidGBZAoJF8EdY yf0Sqv1+zMw6ss1tbRV0e0cQxpQEfl0/1eKJ3KElcNoXifDSVj3WIHDJ//+rmNj9 ionOrGgbTcp5OrDMD6zm7kw8bD70CT2IkKecMaKx3JBV5MnDwAt48gor20QFUWr5 7w6oS3MuI7qHseRDrOT2hEqKGuNsicbAK7U21jheR+9qXBlfSKkMODSJ98WqmZgR WswplJmyG+VnJOrVbtAH =5IyP -----END PGP SIGNATURE-----