[stringtemplate-interest] indexed access to lists
John Snyders
jjsnyders at rcn.com
Fri Jun 1 21:13:35 PDT 2007
There was a recent discussion on this list about indexing into lists
from a template
Nate asks:
Would index access to lists break separation? Eg...
$tests[0].name$
Terence answers:
yep because it is like calling a function with an argument from the
template, not that there aren't similar things.
Calling a function with an argument doesn't bother me much as it is
already done when accessing
the values of a map. The key is passed as an argument and the key is not
limited to an identifier it can
be any string.
I have some different reasons for not liking list indexing
1) the index must be a number and a template shouldn't know anything
about numbers. To me this by itself isn't a very strong argument. I just
have a feeling that there is no need for numbers as such in a template.
Still the index could be a string representation of a number.
2) Indexing lists (or arrays) is really begging for the for loop and
math. This is the main reason why I don't like the list index syntax. I
think the StringTemplate list iteration syntax is much nicer than a
for loop. Allowing math would clearly break separation by allowing
business logic in the template. The indexing syntax could be used to get
a single specific values from the list but most often it is used in
conjunction with for loop iteration.
If you just want one item out of the list have the program put it in a
scalar attribute. If there is truly something special about a single
element then it probably isn't in a list anyway. I think the request for
indexing is mostly about wanting to iterate over a list differently.
Just the first five, all but the last 2, every third one, etc.
One solution for iterating a subset of a list is to have the program
either copy the desired subset to a new list or wrap the list in a new
list that gives out an iterator that returns the subset and provides the
length of the subset. Some reusable wrapper classes could be created.
Example
List sublist = (List) new SliceListWrapper(0, 5, mylist);
SliceListWrapper implements List and in this case would return 5 for
length and the iterator would return elements 0 to 4 inclusive from mylist.
If you really really need to provide indexed access to a list then you
could wrap it in a map. Then you can access item 5 like so $mylist.("5")$.
Another possibility would be to add a slice function to StringTemplate.
It would return a new list with the given range.
Example
$slice(mylist, "0", "5"): { [$it$] }$
would output the first 5 items in mylist enclosed in [].
I'm thinking it would work like Python list slicing.
I think this is safer than list indexing and more in the spirit of
trying to iterate over a subset of a list. It is safe because you are
not calling a method on a user object but a specific string template
function.
Functions first and last should still be kept as convenient shortcuts
and for backward compatibility. The trunc function need not be
implemented now because slice can do it and more.
-John
More information about the stringtemplate-interest
mailing list