[stringtemplate-interest] how to fix longstanding bug
Oliver Flege
o.flege at market-maker.de
Tue Jul 25 01:18:23 PDT 2006
Hi,
Kunle Odutola wrote:
>> Suggestions? I'd really like at least the iterators I create to be
>> "reusable" within same template.
>
> Only sure way is to wrap *all* incoming iterators in a collection of some
> sort. A bit like RestCollection does. Heavy-ish overhead unless, it is
> possible to detect in advance if an iterator is indeed used repeatedly.
>
> C# also has the option of simply Reset()-ing iterators but that breaks with
> "positioned iterators" (i.e. iterators deliberately positioned at a specific
> point in the underlying collection).
in my local (Java) ST code, I fixed this issue by introducing an STIterator class
in the StringTemplate class (see below).
That class is used to wrap any iterator that is either set with setAttribute or
that is created during template evaluation; its reset() method is called whenever
a local attribute is retrieved in StringTemplate#get that is-a STIterator, thus
referencing an iterable object more than once always yields a "fresh" iterator.
The cost for copying all elements into a private list upon construction
is (at least for me) negligible:
On a 2GHz P4 machine, I can create 1000 STIterators with 100 elements each in about 10ms.
Oliver
public static final class STIterator implements Iterator {
private final List list;
private final Iterator it;
public static STIterator create(Map m) {
return new STIterator(m.entrySet());
}
public static STIterator create(Collection c) {
return new STIterator(c);
}
public static STIterator create(Iterator i) {
return new STIterator(i);
}
private STIterator(Collection c) {
this.list = new ArrayList(c.size());
this.list.addAll(c);
this.it = this.list.iterator();
}
private STIterator(Iterator it) {
this.list = new ArrayList();
while (it.hasNext())
this.list.add(it.next());
this.it = this.list.iterator();
}
private STIterator(List list) {
this.list = list;
this.it = this.list.iterator();
}
public boolean hasNext() {
return this.it.hasNext();
}
public Object next() {
return this.it.next();
}
public void remove() {
throw new UnsupportedOperationException();
}
public STIterator reset() {
return new STIterator(this.list);
}
public STIterator rest() {
if (this.list.size() < 2) {
return null;
}
return new STIterator(this.list.subList(1, this.list.size()));
}
}
More information about the stringtemplate-interest
mailing list