You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@velocity.apache.org by Christopher Schultz <ch...@christopherschultz.net> on 2013/05/15 18:11:06 UTC

"While"-like structure in Velocity?

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


Re: "While"-like structure in Velocity?

Posted by Christopher Schultz <ch...@christopherschultz.net>.
Claude,

On 5/15/13 1:40 PM, Claude Brisson wrote:
>> #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.
> 
> Even if the queue is materialized by a linked list rather than by an
> array? #foreach over a linked list is the way to go, I think.

I think the iterator will bomb as soon as I mutate the queue with
ConcurrentModificationException, no?

-chris


Re: "While"-like structure in Velocity?

Posted by Claude Brisson <cl...@renegat.net>.
> #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.

Even if the queue is materialized by a linked list rather than by an
array? #foreach over a linked list is the way to go, I think.


  Claude

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@velocity.apache.org
For additional commands, e-mail: user-help@velocity.apache.org


Re: "While"-like structure in Velocity?

Posted by Christopher Schultz <ch...@christopherschultz.net>.
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


Re: "While"-like structure in Velocity?

Posted by Sergiu Dumitriu <se...@gmail.com>.
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

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@velocity.apache.org
For additional commands, e-mail: user-help@velocity.apache.org


Re: "While"-like structure in Velocity?

Posted by Christopher Schultz <ch...@christopherschultz.net>.
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?

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.

Thanks,
-chris


Re: "While"-like structure in Velocity?

Posted by Sergiu Dumitriu <se...@gmail.com>.
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

-- 
Sergiu Dumitriu
http://purl.org/net/sergiu

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@velocity.apache.org
For additional commands, e-mail: user-help@velocity.apache.org