[antlr-interest] Re: StringTemplate enhancement question

birmanstefan stefan at amiq.ro
Tue Jun 22 12:07:16 PDT 2004


See comments inside :
--- In antlr-interest at yahoogroups.com, Terence Parr <parrt at c...> 
wrote:
> 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"})

  I would prefer something like :

       st.setAttributesFor("tokens", VectorOfIds, VectorOfValues) or 
better st.addAttributesFor(....).

Where Vector of id's is the vector of tokens.id(attributes). Current 
value in VectorOfValues(properties) will be associated to 
VectorOfIds.get(currentIndex%VectorOfIds.size()), where % is modulo.
The bad thing is that user must keep in mind to put in VectorOfValues 
a value for each id (N*VectorOfIds.size()), otherwise the values will 
be scrambled. Another issue would be the mechanism behind the scene, 
which would have to spread the values in the right places.
If in the vectors will be objects then you can use classic mechanism 
of getProperty().

Hope it helps,
              Stefan.
 
> 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