[stringtemplate-interest] how to fix longstanding bug

Terence Parr parrt at cs.usfca.edu
Mon Jul 24 18:06:59 PDT 2006


Ok, so a bug exists with the rest(attribute) operator.  If you pass  
the result as a parameter it gets mess up if you ref that parameter  
 >1 time.  Here is the unit test that fails:

	/** BUG!  Fix this.  Iterator is not reset from first to second $x$
	 *  Either reset the iterator or pass an attribute that knows to get
	 *  the iterator each time.  Seems like first, tail do not
	 *  have same problem as they yield objects.
	 *
	 *  Maybe make a RestIterator like I have CatIterator.
	 */
	public void testRepeatedRestOpAsArg() throws Exception {
		String templates =
				"group test;" +newline+
				"root(names) ::= \"$other(rest(names))$\""+newline+
				"other(x) ::= \"$x$, $x$\""+newline
				;
		StringTemplateGroup group =
				new StringTemplateGroup(new StringReader(templates),
										DefaultTemplateLexer.class);
		StringTemplate e = group.getInstanceOf("root");
		e.setAttribute("names", "Ter");
		e.setAttribute("names", "Tom");
		String expecting = "Tom, Tom";
		assertEqual(e.toString(), expecting);
	}

It yields "Tom, " not "Tom, Tom".  I said, "oh, just reset iterator  
when you hit the end".  There *is* no reset method!  i cannot reset  
any incoming attributes as the following unit test shows:

	/** If an iterator is sent into ST, it must be cannot be reset after  
each
	 *  use so repeated refs yield empty values.  This would
	 *  work if we passed in a List not an iterator.  Avoid sending in  
iterators
	 *  if you ref it twice.
	 */
	public void testRepeatedIteratedAttrFromArg() throws Exception {
		String templates =
				"group test;" +newline+
				"root(names) ::= \"$other(names)$\""+newline+
				"other(x) ::= \"$x$, $x$\""+newline
				;
		StringTemplateGroup group =
				new StringTemplateGroup(new StringReader(templates),
										DefaultTemplateLexer.class);
		StringTemplate e = group.getInstanceOf("root");
		List names = new ArrayList();
		names.add("Ter");
		names.add("Tom");
		e.setAttribute("names", names.iterator());
		String expecting = "TerTom, ";  // This does not give TerTom twice!!
		assertEqual(e.toString(), expecting);
	}

Suggestions?  I'd really like at least the iterators I create to be  
"reusable" within same template.

Ter


More information about the stringtemplate-interest mailing list