[stringtemplate-interest] Maps with object keys
Caleb Lyness
caleb.lyness at ezswitch.net
Fri Nov 30 05:06:33 PST 2007
John Snyders wrote:
> I wrote down my thoughts on what the data model for string template
> should be here:
>
> http://hardlikesoftware.com/weblog/2007/06/01/thoughts-on-stringtemplate-part-1/
>
> I wrote "The keys of a map must be scalar strings.". I was not
> writing about the current implementation
> but about some idealized StringTemplate language. So why did I write
> this? I'm sure I'm giving it more
> thought now than when I originally wrote it.
>
> The StringTemplate data model consists of scalars, lists and maps (yes
> it also has objects but I think these
> should be treated like maps from the template point of view). The only
> scalar type it has a literal syntax for
> is a string. The only other scalar type it knows anything about is
> boolean which it only uses in if expressions.
> Basically StringTemplate has a very limited set of data types that it
> knows about. I think this is a good thing.
>
> StringTemplate's job is to turn what you give it into strings -
> nothing more.
Hmmm, I fell into the trap of working with objects because it seemed a
natural key, given that I was iterating
over a list of objects as compared to a list of strings.
"$hammers:{hammer|$stock.(hammer);null=\"0\"$}$"
I can see your point, but you must admit that it does not make it a particularly natural
way to work:
Map<String,Integer> hammersInStock = new HashMap<String,Integer>();
hammersInStock.put(Hammer.MALLET.toString(), 5);
hammersInStock.put(Hammer.CLUB.toString(), 2);
st.setAttribute("stock", hammersInStock); // map with key as object.toString
st.setAttribute("hammers", hammers); // list of objects
String result = st.toString();
One has to know in detail what string template will do with the object to know if one must
insert a string or an object. If maps are only allowed to be indexed on a string then
a specialised map should be used and not a generic one accepting objects as the key. Restrictions
should be reflected clearly by the interface (usability-101). But I am getting side tracked.
>
> However it does have an important characteristic. It lets scalars
> pass through without type conversion
> from the program that created them to the renderer. This allows the
> renderer to do type specific formatting.
> The default is a call to toString on the object. The renderer may know
> about the objects type but the template
> should not know or care what type an attribute is other than is it a
> scalar, list or map.
One does not add any additional type information here:
m.(x) gives
value = m.get(x)
if (value == null) value = m.get(x.toString())
x is still a "scalar" we know that m is a map. For maps we check for the
scalar x before stringifying it and checking again.
>
> So although the scalar arguments that StringTemplate processes are
> arbitrary types the only thing that
> it knows to do with them is turn them into strings.
It knows how iterate over a collection of objects. That's a bit more
than turning objects directly to strings. It also know about
null objects.
> Giving StringTemplate the ability to do any more than
> this (even in limited contexts) moves it closer to a general data
> processing engine.
>
> We all know about how maps can be used to get around the view
> separation (at the programmers
> discretion not the template writers). Allowing arbitrary types to be
> passed to the "map" would make
> this easier to abuse. Currently if you wanted to pass complex data to
> the map you need to serialize it as a string.
Can you explain more or give an example of how using an object as a map
key would make it easier to abuse than it currently is?
>
> It makes sense to me that enums (hammer in the example) would be
> converted to strings when used
> like this $stock.(hammer);null="0"$
Yes, it makes sense. But "stock" should only be allowed to be string
based map... their would be no chance for confusion.
>
> The underlying question that this issue brings up is: should
> StringTemplate be able to deal with any and all
> data structures the host language (e.g. Java) can implement or should
> the program and it's data meet
> StringTemplate half way?
No. No additional type support required.
>
> StringTemplate does a lot already to make existing data structures
> consumable to templates. But I don't think
> it should be expected to handle everything. Maps with non String keys
> are an example.
>
> There are already any cases where ST requires the data model to
> change. For example if you had a
> property for accountBalance you may need to add a property called
> overdrawn because StringTemplate
> doesn't do math or comparisons.
>
> All this being said I wonder if an exception should be made for enums.
>
> Caleb, in your original example was Product an enum or are you looking
> for maps with other key types?
It is an enum in the non java 5.0 sense
public class Product {
public static X = Product("PX",10);
public static Y = Product("PY",20);
private Product(String name, long code) {
....
}
....
}
>
> One problem I can see with a special case for enums is that ST doesn't
> require Java 5.
Java 5 just adds a nice syntax for the enum concept. Still a very real
pattern pre Java 5.
>
> -John
>
> Caleb Lyness wrote:
>> Terence Parr wrote:
>>> Hi Caleb! :)
>>>
>>> Heh, yeah, you're right...this is weird, though consistent with what
>>> (x) means..(x) means "take the value of" or "immediately eval" rather
>>> than lazy eval. Sometimes you need to render an expression such as
>>> for keys with maps. It's an indirection and immediate eval.
>>>
>>> m.x gives m.get("x")
>>> m.(x) gives m.get(x.toString())
>>> m.(x+"foo") gives m.get(x + "foo")
>>>
>>> hmm...we do need a map look up with an object...i wonder what to do...
>>>
>> Well as a step toward resolving the problem have a look at the
>> attached test case.
>> Perhaps you would like to add it to TestStringTemplate and create an
>> issue report
>> for the problem?
>>
>> Cheers
>> Caleb
>>> Ter
>>>
>>> On Nov 23, 2007, at 3:34 AM, Caleb Lyness wrote:
>>>
>>>
>>>> Hi all,
>>>>
>>>> I have not been keeping up to date with my string template mails...
>>>> perhaps this has been covered before, just point me at the thread
>>>> if already covered...
>>>> This is also being tested against ST-3.0.
>>>>
>>>> Here is a segment of a test template:
>>>>
>>>> $products: {product |
>>>> <tr>
>>>> <td>$product$</td>
>>>> <td>$report.productReadStats.(product);null="0"$</td>
>>>> <td>$report.productActivationsStats.(product);null="0"$</td>
>>>> <td>$report.productIssuedStats.(product);null="0"$</td>
>>>> </tr>}$
>>>>
>>>> On the model side I had:
>>>>
>>>> public HashMap<Product, Integer> productReadStats = new
>>>> HashMap<Product, Integer>();
>>>> public HashMap<Product, Integer> productIssuedStats = new
>>>> HashMap<Product, Integer>();
>>>> public HashMap<Product, Integer> productActivationsStats = new
>>>> HashMap<Product, Integer>();
>>>>
>>>> String template would always report the stats as 0 (via the null
>>>> setting). My guess from what I am seeing
>>>> is that ST-3.0 is dereferencing (product) to a string and not an
>>>> object. When looking up the value in the
>>>> map the string does not result in the correct map reference.
>>>>
>>>> Changing my map to a string based key:
>>>>
>>>> public HashMap<String, Integer> productReadStats = new
>>>> HashMap<String, Integer>();
>>>> ... etc ...
>>>>
>>>> resulted in the correct values.
>>>>
>>>> Is this a known problem/limitation? Or is this considered the
>>>> correct behaviour. Surely an attempt should be
>>>> made to lookup the object directly and then use the object.toString
>>>> () as the key as a 2nd attempt?
>>>>
>>>> Cheers
>>>> Caleb.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.antlr.org:8080/pipermail/stringtemplate-interest/attachments/20071130/d69d11fb/attachment-0001.html
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/x-pkcs7-signature
Size: 3269 bytes
Desc: S/MIME Cryptographic Signature
Url : http://www.antlr.org:8080/pipermail/stringtemplate-interest/attachments/20071130/d69d11fb/attachment-0001.bin
More information about the stringtemplate-interest
mailing list