[antlr-interest] StringTemplate enhancement question
Terence Parr
parrt at cs.usfca.edu
Tue Jun 22 10:48:29 PDT 2004
To anyone playing with StringTemplate...
First, good news. The use of StringTemplate 2.0b1 in my ANTLR 3.0 code
generator is a truly a joy.
Next, I have a problem. Recall that the distinguishing characteristic
of ST is that it strictly enforces separation of model and view; that
is, your view literally cannot become part of the program. This
manifests itself in, for example, the ANTLR code generator as a
guarantee that the CodeGenerator object is truly language-independent
and consequently ANTLR should be easily retargetable. Literally every
character that goes out to the generated Java file comes from a
template; no literals in the CodeGenerator. :)
Ok, on to my desired enhancement...
I often have lists of things that need to be formatted, but the list
items are actually pieces of data that are not already in an object. I
need ST to do something like:
Ter=3432
Tom=32234
....
using template:
$items:{$attr.name$=$attr.type$}$
This example will call getName() on the objects in items attribute, but
what if they aren't objects? I have perhaps two parallel arrays
instead of a single array of objects containing two fields. One
solution is allow Maps to be handled like properties so that attr.name
would fail getName() but then see that it's a Map and do
attr.get("name") instead.
This very clean approach is espoused by some, but the problem is that
it's a hole in my separation rules. People can put the logic in the
view because you could say: "go get bob's data" in the view:
Bob's Phone: $db.bob.phone$
A view should not be part of the program and hence should never be able
to go ask for a specific person's data. Humor me that it's good to be
ruthless (or read my paper <snicker>). Is there another way to fake
aggregates by given separate pieces of data to ST and have it
aggregate?
Well, first I tried passing in
new Object() {
public String getName() {return "Ter";}
public String getType() {return "234";}
}
But it complains that the damn anonymous class is not public :(
Bastards! Those things suck.
So, what about something like:
st.setAttribute("items.name", "Ter");
st.setAttribute("items.type", "342");
But that isn't quite it. How does ST know when to make a new items
object in the list versus setting a prop within the last item added or
whatever. Or, what about a new method:
st.setupAttribute("items.name", "Ter");
st.setupAttribute("items.type", "342");
st.nextAttribute();
er something?
Seems like the various pieces could go in together like this:
st.setAttribute("tokens.name,type", new Object[] {"Ter","342"});
which is weird, but would work. I'd have to parse the attribute name a
bit and pull apart stuff to make a little hashtable out of name/type.
I suppose I could pass two arrays: one for the names and one for the
values. Ick. Could do this I suppose:
st.setAttribute("tokens", new Object[] {"name","Ter","type","342"});
Just intersperse the keys with the values. gross ;)
A final option. Believe it or not, due to the wacky init {...} syntax
for anon inner classes, this would work too:
st.setAttribute("tokens", new HashMap() {{put("name","Ter");
put("type","342");}});
The double {{ }} would be required. That is, the following code
HashMap m = new HashMap() {{put("name","Ter"); put("type","342");}};
System.out.println(m);
prints
{type=342, name=Ter}
Again, though, how do I prevent people from passing in a regular
HashMap that is actually just a proxy for their DB? Then the view
could do DB accesses! Oh, I could make a special object that worked
like a HashMap, but which wouldn't allow subclasses so people couldn't
sneak in a modified version that was actually a database.
Which would you choose? Anybody have some insight?
Ter
--
CS Professor & Grad Director, University of San Francisco
Creator, ANTLR Parser Generator, http://www.antlr.org
Cofounder, http://www.jguru.com
Cofounder, http://www.knowspam.net enjoy email again!
Cofounder, http://www.peerscope.com pure link sharing
Yahoo! Groups Links
<*> To visit your group on the web, go to:
http://groups.yahoo.com/group/antlr-interest/
<*> To unsubscribe from this group, send an email to:
antlr-interest-unsubscribe at yahoogroups.com
<*> Your use of Yahoo! Groups is subject to:
http://docs.yahoo.com/info/terms/
More information about the antlr-interest
mailing list