[stringtemplate-interest] String manipulations
John Snyders
jjsnyders at rcn.com
Thu Sep 28 12:29:00 PDT 2006
> -----Original Message-----
> From: Terence Parr
> Subject: Re: [stringtemplate-interest] String manipulations
>
> On Sep 27, 2006, at 9:39 PM, John Snyders wrote:
>
> > Sorry the response is so long. I am new to ST and also need to
> > think things
> > through in writing.
>
> Hi John, this is an awesome summary of the situation...hope you don't
> mind if I CC the list.
Thanks, not at all.
> > Option 3 looks like any normal template invocation over a
> > collection. Again
> > one would not expect a template to have an effect on rendering.
>
> Well, I'd say you're right, but rendering and apply-template are very
> similar in concept, just not implementation.
>
> Option 3 has the problem of "caching/reloading from disk"; the
> renderers are not set automatically for upperCase template. If the
> template is thrown out and reloaded by ST group then the renderer is
> lost.
Now I finaly understand what you talkig about. This seems to be a general
problem. If it makes sense to have per StringTemplate renderers then they
shouldn't be lost just because the cache is flushed. Or perhaps the rule is
that templates from disk can't have renderers.
I guess I didn't have that problem because the upperCase template was
created from code.
>
> > That would just leave scalar attributes and maps, and public object
> > fields. But wait I can implement the same functionality as above
> > with a map.
> > Just create a class that implements Map and the get method can do
> > anything
> > with the key string. Example of use: $badmap.({+,3,5})$. You were
> > probably
> > aware of this. The old documentation says: "You may pass in
> > instances of
> > type HashMap and Hashtable but cannot pass in objects implementing
> > the Map
> > because that would allow all sorts of wacky stuff like database
> > access." But
> > now you can pass in Map. What changed your mind?
>
> There is a case where you want to have Map access strings for i18n in
> a database. The potential for abuse is there as you've shown with
> badmap above. My philosophy is to make bad behavior as inconvenient
> as possible and to clearly highlight it (getName() wiping drive)
> while still allowing flexibility and being a practical system.
Yes I also have a use for my own Map. I'll write about it later.
> > Here is another distinction between options 2, 3, and 4. With
> > option 2 there
> > is no way that the rendering can be applied to anything but the
> > value of the
> > attribute. With 3 the rendering done by the template upperCase can
> > apply to
> > attributes, string literals, and templates.
>
> Very true. Hadn't thought of that.
>
> > When applied to templates only
> > attributes referenced within that template get uppercased. Example
> > from my
> > previous email (correcting the typo):
> > $upperCase(it={$message(p0=name)$})$ produces: "Hello JOHN!"
> > "Not HELLO
> > JOHN"
>
> If args are defined you can say:
>
> $upperCase({$message(name)$})$
>
> Hmm...sees that the whole message should be uppercased, but youre
> right...it only does on the renderering of attributes not string
> literals. So option 3 seems not so good.
Yes, I think option 3 should be dismissed.
> > With option 4 I think the expected behavior is that the formatting
> > would
> > apply to the whole template. The reason is that the ;separator syntax
> > applies to templates as in:
> > $requestParameters.(k) : {[$it$]}; separator=", "$ which produces a
> > comma
> > separated list of values enclosed in square brackets (ex: [a], [b],
> > [c]).
> > So I would expect ${ hello $name$!};format="upperCase"$ to produce
> > "HELLO
> > JOHN!"
>
> Correct.
>
> > Another problem with option 4 is that the template makes
> > assumptions about
> > the types of attributes. For example if format short applies to
> > dates then
> > $name;format="short"$ makes no sense. This breaks your rule 4.
>
> What if format="foo" didn't call foo() on the object? What if it
> called format(object,"foo") with "foo" as the format string? If
> format is defined, cool else it's ignored.
>
> Actually doesn't this present the renderer problem again? String
> would have to have a renderer defined...oh, but you could do that
> globally with a singleton renderer registered for String. If you
> ever anywhere said $somestring; format="abbrev"$, the
> stringRenderer.format(somestring, "abbrev") would be called.
> Hmm...opens things up a bit, but I guess if format wipes the drive
> it's clear you're abusing the format method.
I think all these questions are moot given that the singleton render can be
applied to the syntax of option 4 as described below.
>
> > If this is the difference then YES I think it is the right solution
> > for the
> > implementation.
>
> Meaning the name.toUpper or name; format="toUpper"?
I like $name; format="toUpper"$ because it s clear what the intention is. No
question about if .toUpper is a property or formatter.
> > It constrains the possible set of renderers to just what the
> > renderer class provides and makes it very clear what should happen
> > when
> > there is a type mismatch. (renderer.get("String") should return
> > null if it
> > doesn't know what to do with strings and then the next step would be
> > skipped.)
> >
> > However I think the implementation is independent of the syntax
> > used. Why
> > couldn't option 4 ($name;format="upperCase"$) be translated to
> > r = renderer.get("String");
> > r.upperCase(name);
>
> Interesting...ok, we don't want $x; format="y'$ to call x.y(), but we
> can allow it to call $xClassRenderer.y(x)$. That is better...
You had already proposed the solution. I just noticed that it can apply to
the ;format= syntax.
>
> I have also just increased use of options such as wrap so this is not
> a new "concept".
I still need to learn about wrap
> > To sum up I would like to see option 4 supported and implemented as
> > you
> > described. The formatting would apply to (the result of) templates
> > to be
> > consistent with the ;separator.
>
> Yes, so I'd evaluate the entire expressions even if
>
> $names:{$i$. <b>$it$</b>}$; format="upperCase"$
>
> Here, the entire list of crap would be uppercased including the $i$
> numbers. Right?
Yes I think that makes sense.
> > If there is a type mismatch (such as
> > $today;format="upperCase"$ where upperCase works on Strings and
> > today is a
> > Date) then the empty string is returned (or perhaps an exception
> > would be
> > better). Using a format string that doesn't exist as a method could
> > also be
> > defined to return an empty string or throw an exception (not sure
> > which is
> > best).
>
> Hmm...I think perhaps that should reduce to simply $today$ if there
> is no formatter...perhaps that allows you to remove a renderer w/o
> breaking stuff?
I would be fine with this. Perhaps a warning could be given.
> > This handling of type mismatches and unsupported formats with option 4
> > syntax is preferred over the option 2 syntax. Option 2 would end up
> > potentially hiding properties. The person creating properties and
> > the person
> > defining renderers would have to coordinate because they are
> > sharing the
> > same namespace. Option 4 is a little more efficient since you know
> > you are
> > done if you don't find a format method you don't have to go looking
> > for a
> > property.
>
> I think we'll need a severity/pendantic option for ST soon so you can
> say what becomes an exception and what is ignored.
If each distinct error case had an identifier then the
StringTemplateErrorListener implementation could decide what to ignore, what
to log and what to throw.
-John
More information about the stringtemplate-interest
mailing list