4

I have a problem with the recently released beta version of Stringtemplate 4.

In StringTemplate 3, I used to have templates like

<env_vars:{ var | void* <var>() { return null; }}>

i.e. anonymous templates containing a literal closing brace ("}"), and these worked well enough in ST3 without escaping the first closing brace.

With ST4, I'm getting a NPE (the test case below prints the stack trace). I can get it to work by escaping the closing literal brace, so the template looks like this (notice the quoting backslash in front of the first closing brace):

<env_vars:{ var | void* <var>() { return null; \}}>

But it seems a bit ugly; I've always admired ST's non-intrusive syntax and having to match each "{" to be output with a corresponding "\}" somehow seems very asymmetrical.

Is there something I'm missing or is this an expected change in behavior from ST3?

Test case:

import org.stringtemplate.v4.ST;

public class ST4Test
{
  public static void main(final String[] args)
  {
    final String[] env_vars = new String[]{"one", "two", "three"};

    try
    {

      // This used to work in ST3, but fails in ST4.
      final ST failingST = new ST("<env_vars:{ var | void* <var>() { return null; }}\n>");
      failingST.add("env_vars", env_vars);

      System.out.printf("%s\n", failingST.render());
    }
    catch (Exception ex)
    {
      // The failing example results in a NPE
      ex.printStackTrace();
    }

    // This works, but requires quoting the "}" contained within the anonymous
    // template, which I find a bit disturbing, considering that I use ST for
    // generating C-code, which tends to use the occasional "}", along with the
    // fact that this used to work in ST3.
    final ST workingST = new ST("<env_vars:{ var | void* <var>() { return null; \\}\n}>");
    workingST.add("env_vars", env_vars);
    System.out.printf("%s\n", workingST.render());
  }
}
pmf
  • 7,619
  • 4
  • 47
  • 77

1 Answers1

4

I get

test 1:44: invalid character '}'

Are you sure that worked in ST3? The inside } matches but, like quotes, the first } should terminate the template. ST should not interpret text inside templates at all. How about this?

<env_vars:{ var | void* <var>() {{{{{{{{{{{ return null; }>

That should work but wouldn't if i looked at { inside. it could be the head not complete func you're generating, right?

Sounds like v3 had a bug! ;)

Ter

Terence Parr
  • 5,912
  • 26
  • 32
  • I've fixed the markup of the test case (the important part was half missing). My uneducated guess as to why it has worked in ST3 would be than it used some kind of lookahead to determine whether a closing } was followed by a template closing character (greater-than resp. dollar, for the outer template), and only then interpreted it as closing token for the anonymous template. – pmf Jan 19 '11 at 21:10