[prev in list] [next in list] [prev in thread] [next in thread] 

List:       velocity-user
Subject:    Re: "While"-like structure in Velocity?
From:       Christopher Schultz <chris () christopherschultz ! net>
Date:       2013-05-16 17:18:32
Message-ID: 519514E8.3060505 () christopherschultz ! net
[Download RAW message or body]


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)]

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic