You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@velocity.apache.org by bob mcwhirter <bo...@werken.com> on 2001/05/18 22:22:05 UTC

iterator() && #foreach

Howdy folks..

More mail along the lines of put(...) being used for #set
directives, but this time, it's the usage of iterator() 
for #foreach directives.

Currently, it appears, I think, that the object of a #foreach
must either be an Iterator or implement the Collection interface.

What I'd personally really like, is if it doesn't implement 
Collection, then just go looking for a method of the signature

	Iterator iterator()

Basically, in ForEach.java, the getIterator() method, the
very end, towards the switch statement, change the default
case to use util/Introspector to find/invoke a method
named 'iterator' with no args.

That'll increase the usefulness of Velocity, I believe.

If I can get 3 votes, I'll implement it m'self.

	-bob


Re: iterator() && #foreach

Posted by bob mcwhirter <bo...@werken.com>.
> > btw, I know you're attempting to release eary and often, so just
> > curious if you have any rough target for a 1.2 with the new iterator()
> > muckage added?  I personally don't mind using CVS snapshots, but
> > management would be more comfortable with a named release, of course.
> 
> You being management :)

Fortunately, no. ;)

> If not, we can shoot for 1.2 as the interator(), the new put(), and the
> foreach optimization - try to get earlier and oftener.  However, 1.0.1
> was released 4/23, so it hasn't even been a month...

Perfect!

> > We've started using Velocity actively in-house now (in caps.com
> > products), so expect to see me more often.
> 
> Excellent.  Didn't you have your own lightweight template engine?

Yah, but I'd rather go with something that is more 'standard' and
has a larger installed user (and thus support) base.  I didn't want
to be the sole support person in my org for the template engine 
we use.  

	-bob


Re: iterator() && #foreach

Posted by "Geir Magnusson Jr." <ge...@optonline.net>.
bob mcwhirter wrote:
> 
> > It feels wrong for some reason, but I can't come up with a rational
> > reason why. :)  It might be because the JSP users in tomcat-dev got me
> > thinking dark thoughts about looping...
> 
> My thought is that looping should be possible over things
> that consider themselves collections, not neccessarily
> directly implementing java.util.Collection.
> 
> If something provides an iterator() method, that's truly the
> only portion of the Collection interface contract we care
> about, so why burden the class with having to implement
> all other methods of Collection to be #foreach-able.

Ya.  I agree.  That's why I can't come up with a rational reason.  But
something bothers me...  Doesn't matter...

> > I think it should be post 1.1... I am doing my best to roll out the 1.1
> > now, just getting to the final nips and tucks.  I have something to do
> > in foreach right after - Kaspar did some good optimization work towards
> > removing the <what should be gratuitous...> object creation in the loop
> > - so if I am in there, and you don't care, I can drop that in.
> 
> Sure, if you want to drop in the code, that's hunky-dorey to me.
> 
> btw, I know you're attempting to release eary and often, so just
> curious if you have any rough target for a 1.2 with the new iterator()
> muckage added?  I personally don't mind using CVS snapshots, but
> management would be more comfortable with a named release, of course.

You being management :)

I am staring at a context issue, so there may be more change, so we
might drop this into 1.1 :)

If not, we can shoot for 1.2 as the interator(), the new put(), and the
foreach optimization - try to get earlier and oftener.  However, 1.0.1
was released 4/23, so it hasn't even been a month...

> > Otherwise, welcome back :)
> 
> So, I'm not welcome if you perform the code edits? ;) <joke!>

Phrased as it was, that's the logical conclusion.

LOL
 
> We've started using Velocity actively in-house now (in caps.com
> products), so expect to see me more often.

Excellent.  Didn't you have your own lightweight template engine?

geir

-- 
Geir Magnusson Jr.                           geirm@optonline.net
System and Software Consulting
Developing for the web?  See http://jakarta.apache.org/velocity/
"still climbing up to the shoulders..."

Re: iterator() && #foreach

Posted by "Geir Magnusson Jr." <ge...@optonline.net>.
bob mcwhirter wrote:
> 
> > > If something provides an iterator() method, that's truly the
> > > only portion of the Collection interface contract we care
> > > about, so why burden the class with having to implement
> > > all other methods of Collection to be #foreach-able.
> >
> > What you can do is to implement Iterator instead. There are only three
> > methods of which remove is optional. Look at RS wrapper (inner class
> > TableTool) at:
> 
> Yeahbut... in my current design, the object in question
> is a collection of things that can be iterated over.  Not
> an iterator itself.
> 
> If TheObject implemented Iterator, instead of providing
> an iterator() method, then only a single thread at a time
> could be using it as an iterator, since TheObject contains
> iterator state, allowing for next() to actually produce the
> next element.
> 
> Iterators can't be shared.  Read-only collections can be.

I think it's worse than that, as there is no standard provision for
resetting an Iterator.  Vel supports Iterator and Enumeration, but
theres a caution in the docs because you can only use once.

geir

-- 
Geir Magnusson Jr.                           geirm@optonline.net
System and Software Consulting
Developing for the web?  See http://jakarta.apache.org/velocity/
"still climbing up to the shoulders..."

Re: iterator() && #foreach

Posted by "Geir Magnusson Jr." <ge...@optonline.net>.
Fedor Karpelevitch wrote:
> 
> On Sunday 20 May 2001 06:12, you wrote:
> > > > If something provides an iterator() method, that's truly the
> > > > only portion of the Collection interface contract we care
> > > > about, so why burden the class with having to implement
> > > > all other methods of Collection to be #foreach-able.
> > >
> > > What you can do is to implement Iterator instead. There are only three
> > > methods of which remove is optional. Look at RS wrapper (inner class
> > > TableTool) at:
> >
> > Yeahbut... in my current design, the object in question
> > is a collection of things that can be iterated over.  Not
> > an iterator itself.
> >
> > If TheObject implemented Iterator, instead of providing
> > an iterator() method, then only a single thread at a time
> > could be using it as an iterator, since TheObject contains
> > iterator state, allowing for next() to actually produce the
> > next element.
> >
> > Iterators can't be shared.  Read-only collections can be.
> 
> makes sense. In this case I would just implement the iterator() method as you
> sain and then do:
> 
> #foreach ($element in $myCollection.iterator())
> ....
> 
> this should work as-is.
> 

:) smarty-pants....

He has a good point here.

geir

-- 
Geir Magnusson Jr.                           geirm@optonline.net
System and Software Consulting
Developing for the web?  See http://jakarta.apache.org/velocity/
"still climbing up to the shoulders..."

Re: iterator() && #foreach

Posted by ji...@respublica.fr.
This discussion is interesting
Don't you think we are ending up with too many fallbacks here?
There is the Iterator class, the Collection interface (not needed any 
more when we have the next one:), iterator() public method and single 
item iterator.

Can we get rid of the single item iterator?

We could provide a wrapper (like SingleItemIterator) to decide whether 
we want the object to be singled

Or if we want all objects of a class to be used as a single iterator, it 
would be only the matter of adding the method to the class:

   public Iterator iterator()
   {
       return new SingleItemIterator(this);
   }

The benefits of *not* creating automatically a new SingleItemIterator in 
the default case is that one can easily _add_ the iterating on a single 
object, but it is more difficult to _remove_ the iterator() method if we 
want to treat a collection as a single object (maybe with a wrapper?...)

My 2c


-- Denis.

On Monday, May 21, 2001, at 02:18  am, Geir Magnusson Jr. wrote:

>
>> We could make the getIterator() portion of Foreach pluggable.
>> maybe, and then allow folks to install whatever kind of iterator
>> fetcher that they want.  ie, our personal default: case would
>> be to create a new SingleItemIterator( listObj ) if that's what
>> we wanted.
>>
>> Though, not this week. ;)
>
> No. :)  However, I do sort-of believe that limiting the options here is
> a good idea - adding the single item iterator (if the search for
> supported iterators fails...), and having the .iterator() should really
> cover all the bases.
>
> What is added if it's pluggable?  We still would have to agree on what
> it would have to return to velocity so vel could iterate, and Iterator
> is a darn fine solution.  Therefore, if you have support for a  public
> Iterator iterator(), what would you need anything else for?
>
> In other words, if we do a pluggable, we would maybe decide that the
> pluggable interface thingy must return an Iterator to velocity...
>
> geir
>
>
>>         -bob
>
> --
> Geir Magnusson Jr.                           geirm@optonline.net
> System and Software Consulting
> Developing for the web?  See http://jakarta.apache.org/velocity/
> "still climbing up to the shoulders..."
>

Re: iterator() && #foreach

Posted by "Geir Magnusson Jr." <ge...@optonline.net>.
bob mcwhirter wrote:
> 
> 
> > Bob, it's not that big a deal... consider it in there...
> 
> Hokie dokie.  Much thanks.

Just to be clear, I didn't phrase that right, appearing to hijack
discussion - I don't want to stop any discussion if people think it's
bad for any reason - it's just that I think Fedor was just pointing out
an obvious solution (which I sadly forgot about :)

However, since I can't come up with a good reason, I am for it to. :)


> We could make the getIterator() portion of Foreach pluggable.
> maybe, and then allow folks to install whatever kind of iterator
> fetcher that they want.  ie, our personal default: case would
> be to create a new SingleItemIterator( listObj ) if that's what
> we wanted.
> 
> Though, not this week. ;)

No. :)  However, I do sort-of believe that limiting the options here is
a good idea - adding the single item iterator (if the search for
supported iterators fails...), and having the .iterator() should really
cover all the bases.

What is added if it's pluggable?  We still would have to agree on what
it would have to return to velocity so vel could iterate, and Iterator
is a darn fine solution.  Therefore, if you have support for a  public
Iterator iterator(), what would you need anything else for?

In other words, if we do a pluggable, we would maybe decide that the
pluggable interface thingy must return an Iterator to velocity...

geir

 
>         -bob

-- 
Geir Magnusson Jr.                           geirm@optonline.net
System and Software Consulting
Developing for the web?  See http://jakarta.apache.org/velocity/
"still climbing up to the shoulders..."

Re: iterator() && #foreach

Posted by bob mcwhirter <bo...@werken.com>.
> > If I wanted to be evil, I could suggest the true feature
> > we want, which would be allowing #foreach ($item in $singleObject)
> > to iterate over the singleObject, even though it's just a
> > single object, and not a collection.
> 
> You mean a single element?  I have wanted that from the get-go, and
> suggested it a few times.  It think that is certainly the right thing.
> 
> No one else seems to though.

That's a shame.  

> Actually, didn't you once disagree with me on this ?  :) 

Oh, it's quite possible. ;)

I was young and irrational then.

Now I'm just old and irrational.

> Bob, it's not that big a deal... consider it in there...

Hokie dokie.  Much thanks.  

We could make the getIterator() portion of Foreach pluggable.
maybe, and then allow folks to install whatever kind of iterator
fetcher that they want.  ie, our personal default: case would
be to create a new SingleItemIterator( listObj ) if that's what
we wanted.  

Though, not this week. ;)

	-bob


Re: iterator() && #foreach

Posted by "Geir Magnusson Jr." <ge...@optonline.net>.
bob mcwhirter wrote:
> 
> > > Yah, but then I've gotta teach the iterator() syntax to my
> > > designers...
> >
> > You mean teach them to put .iterator() after something?
> 
> Yeah, and why we only have to do .iterator() sometimes, with
> some things, and not other times, with other things.

I just wanted to make sure there wasn't any confusion, if you thought
you had to teach them about hasNext() and such... :)

> Just curious, are you guys just offering work-arounds, or
> are y'all voting against adding the introspection of iterator()
> feature to Velocity?
> 
> If I wanted to be evil, I could suggest the true feature
> we want, which would be allowing #foreach ($item in $singleObject)
> to iterate over the singleObject, even though it's just a
> single object, and not a collection.

You mean a single element?  I have wanted that from the get-go, and
suggested it a few times.  It think that is certainly the right thing.

No one else seems to though.

Actually, didn't you once disagree with me on this ?  :) 

> My work-around to that wacky request is to simply add an
> iterator() to my single object, and have it return a home-grown
> SingleObjectIterator for #foreach to play with.
> 
> Why?
> 
> Because, depending on things determined only at the last second
> during the parse of a template, $foo might be a java.util.List,
> or it might just be a single object.
> 

Yes!

> And I personally want #foreach against $foo to always work,
> producing either a single iteration of the loop, or one for
> each element in the List.

Yes

 
> But, I wanted to be sane, and instead just ask for introspecting
> off an iterator(), instead of using instanceof java.util.Collection.
> 
> Anyhow, I think I only have 2 votes thus far.  Anyone else care
> to vote for/against this feature request (introspecting iterator(),
> *not* #foreach working on normal, non-collection, single objects.)

Bob, it's not that big a deal... consider it in there...

-- 
Geir Magnusson Jr.                           geirm@optonline.net
System and Software Consulting
Developing for the web?  See http://jakarta.apache.org/velocity/
"still climbing up to the shoulders..."

Re: iterator() && #foreach

Posted by bob mcwhirter <bo...@werken.com>.
> > Yah, but then I've gotta teach the iterator() syntax to my
> > designers...
> 
> You mean teach them to put .iterator() after something?

Yeah, and why we only have to do .iterator() sometimes, with
some things, and not other times, with other things.

Just curious, are you guys just offering work-arounds, or
are y'all voting against adding the introspection of iterator()
feature to Velocity?

If I wanted to be evil, I could suggest the true feature
we want, which would be allowing #foreach ($item in $singleObject)
to iterate over the singleObject, even though it's just a 
single object, and not a collection.

My work-around to that wacky request is to simply add an
iterator() to my single object, and have it return a home-grown
SingleObjectIterator for #foreach to play with.

Why?

Because, depending on things determined only at the last second
during the parse of a template, $foo might be a java.util.List,
or it might just be a single object.  

And I personally want #foreach against $foo to always work,
producing either a single iteration of the loop, or one for
each element in the List.

But, I wanted to be sane, and instead just ask for introspecting
off an iterator(), instead of using instanceof java.util.Collection.

Anyhow, I think I only have 2 votes thus far.  Anyone else care
to vote for/against this feature request (introspecting iterator(),
*not* #foreach working on normal, non-collection, single objects.)

	-bob


Re: iterator() && #foreach

Posted by "Geir Magnusson Jr." <ge...@optonline.net>.
bob mcwhirter wrote:
> 
> > > Iterators can't be shared.  Read-only collections can be.
> >
> > makes sense. In this case I would just implement the iterator() method as you
> > sain and then do:
> >
> > #foreach ($element in $myCollection.iterator())
> > ....
> >
> > this should work as-is.
> 
> Yah, but then I've gotta teach the iterator() syntax to my
> designers...

You mean teach them to put .iterator() after something?

-- 
Geir Magnusson Jr.                           geirm@optonline.net
System and Software Consulting
Developing for the web?  See http://jakarta.apache.org/velocity/
"still climbing up to the shoulders..."

Re: iterator() && #foreach

Posted by bob mcwhirter <bo...@werken.com>.
> > Iterators can't be shared.  Read-only collections can be.
> 
> makes sense. In this case I would just implement the iterator() method as you 
> sain and then do:
> 
> #foreach ($element in $myCollection.iterator())
> ....
> 
> this should work as-is.

Yah, but then I've gotta teach the iterator() syntax to my
designers...

	-bob


Re: iterator() && #foreach

Posted by Fedor Karpelevitch <fe...@home.com>.
On Sunday 20 May 2001 06:12, you wrote:
> > > If something provides an iterator() method, that's truly the
> > > only portion of the Collection interface contract we care
> > > about, so why burden the class with having to implement
> > > all other methods of Collection to be #foreach-able.
> >
> > What you can do is to implement Iterator instead. There are only three
> > methods of which remove is optional. Look at RS wrapper (inner class
> > TableTool) at:
>
> Yeahbut... in my current design, the object in question
> is a collection of things that can be iterated over.  Not
> an iterator itself.
>
> If TheObject implemented Iterator, instead of providing
> an iterator() method, then only a single thread at a time
> could be using it as an iterator, since TheObject contains
> iterator state, allowing for next() to actually produce the
> next element.
>
> Iterators can't be shared.  Read-only collections can be.

makes sense. In this case I would just implement the iterator() method as you 
sain and then do:

#foreach ($element in $myCollection.iterator())
....

this should work as-is.

Fedor.

Re: iterator() && #foreach

Posted by bob mcwhirter <bo...@werken.com>.
> > If something provides an iterator() method, that's truly the
> > only portion of the Collection interface contract we care
> > about, so why burden the class with having to implement
> > all other methods of Collection to be #foreach-able.
> 
> What you can do is to implement Iterator instead. There are only three 
> methods of which remove is optional. Look at RS wrapper (inner class 
> TableTool) at:

Yeahbut... in my current design, the object in question 
is a collection of things that can be iterated over.  Not
an iterator itself.

If TheObject implemented Iterator, instead of providing
an iterator() method, then only a single thread at a time
could be using it as an iterator, since TheObject contains
iterator state, allowing for next() to actually produce the
next element.  

Iterators can't be shared.  Read-only collections can be.

	-bob


Re: iterator() && #foreach

Posted by Fedor Karpelevitch <fe...@home.com>.
On Saturday 19 May 2001 16:27, you wrote:
> > It feels wrong for some reason, but I can't come up with a rational
> > reason why. :)  It might be because the JSP users in tomcat-dev got me
> > thinking dark thoughts about looping...
>
> My thought is that looping should be possible over things
> that consider themselves collections, not neccessarily
> directly implementing java.util.Collection.
>
> If something provides an iterator() method, that's truly the
> only portion of the Collection interface contract we care
> about, so why burden the class with having to implement
> all other methods of Collection to be #foreach-able.

What you can do is to implement Iterator instead. There are only three 
methods of which remove is optional. Look at RS wrapper (inner class 
TableTool) at:

http://jakarta.apache.org/cvsweb/index.cgi/jakarta-turbine/src/java/org/apache/turbine/torque/TorqueDataDumpTask.java?rev=1.1&content-type=text/vnd.viewcvs-markup

I think this works fine.

Fedor.

Re: iterator() && #foreach

Posted by bob mcwhirter <bo...@werken.com>.
> It feels wrong for some reason, but I can't come up with a rational
> reason why. :)  It might be because the JSP users in tomcat-dev got me
> thinking dark thoughts about looping...

My thought is that looping should be possible over things
that consider themselves collections, not neccessarily
directly implementing java.util.Collection.

If something provides an iterator() method, that's truly the
only portion of the Collection interface contract we care
about, so why burden the class with having to implement
all other methods of Collection to be #foreach-able.

> I think it should be post 1.1... I am doing my best to roll out the 1.1
> now, just getting to the final nips and tucks.  I have something to do
> in foreach right after - Kaspar did some good optimization work towards
> removing the <what should be gratuitous...> object creation in the loop
> - so if I am in there, and you don't care, I can drop that in. 

Sure, if you want to drop in the code, that's hunky-dorey to me.

btw, I know you're attempting to release eary and often, so just
curious if you have any rough target for a 1.2 with the new iterator()
muckage added?  I personally don't mind using CVS snapshots, but 
management would be more comfortable with a named release, of course.

> Otherwise, welcome back :)

So, I'm not welcome if you perform the code edits? ;) <joke!>

We've started using Velocity actively in-house now (in caps.com
products), so expect to see me more often.  

	-bob


Re: iterator() && #foreach

Posted by "Geir Magnusson Jr." <ge...@optonline.net>.
bob mcwhirter wrote:
> 
> Howdy folks..
> 
> More mail along the lines of put(...) being used for #set
> directives, but this time, it's the usage of iterator()
> for #foreach directives.
> 
> Currently, it appears, I think, that the object of a #foreach
> must either be an Iterator or implement the Collection interface.
> 
> What I'd personally really like, is if it doesn't implement
> Collection, then just go looking for a method of the signature
> 
>         Iterator iterator()
> 
> Basically, in ForEach.java, the getIterator() method, the
> very end, towards the switch statement, change the default
> case to use util/Introspector to find/invoke a method
> named 'iterator' with no args.
> 
> That'll increase the usefulness of Velocity, I believe.
> 
> If I can get 3 votes, I'll implement it m'self.
> 

It feels wrong for some reason, but I can't come up with a rational
reason why. :)  It might be because the JSP users in tomcat-dev got me
thinking dark thoughts about looping...

<shrug>

I think it should be post 1.1... I am doing my best to roll out the 1.1
now, just getting to the final nips and tucks.  I have something to do
in foreach right after - Kaspar did some good optimization work towards
removing the <what should be gratuitous...> object creation in the loop
- so if I am in there, and you don't care, I can drop that in. 
Otherwise, welcome back :)

geir
 
-- 
Geir Magnusson Jr.                           geirm@optonline.net
System and Software Consulting
Developing for the web?  See http://jakarta.apache.org/velocity/
"still climbing up to the shoulders..."

RE: iterator() && #foreach

Posted by David Duddleston <da...@i2a.com>.
Sounds like a good idea.

+1

-david

> -----Original Message-----
> From: bob mcwhirter [mailto:bob@werken.com]
> Sent: Friday, May 18, 2001 1:22 PM
> To: velocity-user@jakarta.apache.org
> Subject: iterator() && #foreach
> 
> 
> 
> Howdy folks..
> 
> More mail along the lines of put(...) being used for #set
> directives, but this time, it's the usage of iterator() 
> for #foreach directives.
> 
> Currently, it appears, I think, that the object of a #foreach
> must either be an Iterator or implement the Collection interface.
> 
> What I'd personally really like, is if it doesn't implement 
> Collection, then just go looking for a method of the signature
> 
> 	Iterator iterator()
> 
> Basically, in ForEach.java, the getIterator() method, the
> very end, towards the switch statement, change the default
> case to use util/Introspector to find/invoke a method
> named 'iterator' with no args.
> 
> That'll increase the usefulness of Velocity, I believe.
> 
> If I can get 3 votes, I'll implement it m'self.
> 
> 	-bob