You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by Reinhard Moosauer <rm...@moosauer.de> on 2006/02/13 20:48:08 UTC

c:forEach not working as expected

Hi List,

it seemed clear to me, that this construct:

  <c:forEach items="${t.records}" var="x">
     ... (some inner logic)
  </c:forEach>
 
should be equivalent to this one:

  <%
  for (Iterator it=t.getRecords(); it.hasNext(); ) {
     String x = (String)it.next();
  %>
     ... (some inner logic)
  <% }
  %>

But the forEach-version is not working as expected. What can be wrong?
Here are some quite strange effects:
1. The iterators-method "hasNext()" is called twice for every iteration
    (ok: no problem, if the iterator is clean, but why?)
2. The loop-body is executed after hasNext() returned false.
    But the next()-method is NOT called ??

The c:forEach-iterator seems to operate like this:

Iterator it = t.getRecords();
while (it.hasNext()) {
	String x = (String)it.next();
        boolean still_more = it.hasNext();

        ... here comes the body ...
}

What could this extra-check be good for?

Any help is greatly appreciated.
Kind regards,

Reinhard

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: c:forEach not working as expected

Posted by Len Popp <le...@gmail.com>.
On 2/13/06, Reinhard Moosauer <rm...@moosauer.de> wrote:
> Hi List,
>
> it seemed clear to me, that this construct:
>
>   <c:forEach items="${t.records}" var="x">
>      ... (some inner logic)
>   </c:forEach>
>
> should be equivalent to this one:
>
>   <%
>   for (Iterator it=t.getRecords(); it.hasNext(); ) {
>      String x = (String)it.next();
>   %>
>      ... (some inner logic)
>   <% }
>   %>
>
> But the forEach-version is not working as expected. What can be wrong?
> Here are some quite strange effects:
> 1. The iterators-method "hasNext()" is called twice for every iteration
>     (ok: no problem, if the iterator is clean, but why?)
> 2. The loop-body is executed after hasNext() returned false.
>     But the next()-method is NOT called ??
>
> The c:forEach-iterator seems to operate like this:
>
> Iterator it = t.getRecords();
> while (it.hasNext()) {
>         String x = (String)it.next();
>         boolean still_more = it.hasNext();
>
>         ... here comes the body ...
> }
>
> What could this extra-check be good for?
>
> Any help is greatly appreciated.
> Kind regards,
>
> Reinhard
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: users-help@tomcat.apache.org
>
>

It has to do with the way the iteration code is divided between the
<c:forEach> and </c:forEach> tags. I'm not sure if it *had* to be done
that way; you can dig into the Tomcat and JSTL source if you want to
redesign it. ;-)
--
Len

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: c:forEach not working as expected

Posted by Nikola Milutinovic <al...@yahoo.com>.
--- Reinhard Moosauer <rm...@moosauer.de> wrote:

> Hi List,
> 
> it seemed clear to me, that this construct:
> 
>   <c:forEach items="${t.records}" var="x">
>      ... (some inner logic)
>   </c:forEach>
>  
> should be equivalent to this one:

No. It is roughly equvalent to (see my corrections):

>   <%
>   for (Iterator it=t.getRecords(); it.hasNext(); ) {

    for (Iterator it=t.getRecords().getIterator(); it.hasNext(); ) {

>      String x = (String)it.next();

       Object x = it.next();

>   %>
>      ... (some inner logic)
>   <% }
>   %>

I said roughly, because it can handle arrays, too.

> But the forEach-version is not working as expected. What can be wrong?
> Here are some quite strange effects:
> 1. The iterators-method "hasNext()" is called twice for every iteration
>     (ok: no problem, if the iterator is clean, but why?)

This is normal. Try to locate the java code generated from that tag and see
what it comes to. You'll see something educational. There is no "while ()"
loop. Just "if () else" logic.

> 2. The loop-body is executed after hasNext() returned false.
>     But the next()-method is NOT called ??

That would be strange.

Nix.

__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com 

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org