Deep copy string-template3 attribute?

83 Views Asked by At

I'm very new to stringtemplate and have been experimenting with it for a language translation project.

Anyways, I've defined a Java group file containing the following template:

instantiation(realization, arguments) ::= 
<<new <realization>(<arguments; separator = ", ">)>>

However, I'm struggling with the following example:

private StringTemplate myCurTemplate;

public void foo() {
    myCurTemplate = myGroups.getInstanceOf("instantiation");
    myCurTemplate.setAttribute("realization", "test");
    myCurTemplate.setAttribute("arguments", "p0");
    myCurTemplate.setAttribute("arguments", "p1");

    System.out.println("Starting: " + myCurTemplate);  // "new test(p0, p1)"
}

public void bar() {
    StringTemplate modified = myGroups.getInstanceOf("instantiation");
    modified.setAttribute("realization", "anotherTest");
    modified.setAttribute("arguments", myCurTemplate.getAttribute("arguments"));

    System.out.println("Modified: " + modified);  // "new anotherTest(p0, p1)"

    modified.setAttribute("arguments", "p2");
    System.out.println("Modified: " + modified);  // as expected, "new anotherTest(p0, p1, p2)"
    System.out.println("Original: " + myCurTemplate); // "new test(p0, p1, p2)"
}

Notice how, after adding "p2" to the template, "modified", it also changes "myCurTemplate"... Maybe I've designed the template incorrectly (or inadequately?), but is there some way to do this without modifying the original "myCurTemplate"??

That is, can I somehow make a real copy of myCurTemplate's "arguments" attribute without it being modified by future additions to other template instances? I've looked through the methods and api-documentation without much luck -- I have a feeling I'm just trying to do something that isn't commonly done, or needed with stringtemplate..

Edit: So I was messing around a little more with this in ST4 and came up with this code:

ST x = myGroups.getInstanceOf("instantiation");
x.add("realization", "Realiz");
x.add("arguments", "p0");
x.add("arguments", "p1");

ST y = new ST(x);
y.remove("realization"); 
y.add("realization", "Another");
y.add("arguments", "p6");

print x.render(); // "new Realiz(p0, p1, p6)"
print y.render(); // "new Another(p0, p1, p6)"   

I can modify the "realization attribute without trouble, but run into problems still with argument lists of length > 1. For instance, if I defined the argument list in x as only a single element, then modifying it in y keeps both separate -- as desired (maybe because they both get a separate reference at the time of copying??) For example:

ST x = myGroups.getInstanceOf("instantiation");
x.add("realization", "Realiz");
x.add("arguments", "p0");

ST y = new ST(x);
y.remove("realization"); 
y.add("realization", "Another");
y.add("arguments", "p6");
y.add("arguments", "p3");

print x.render();  // "new Realiz(p0)"
print y.render();  // "new Realiz(p0, p6, p3)"   (like I would expect)
1

There are 1 best solutions below

3
On

(By current I assume you mean myCurTemplate). Hmm...seems I don't make a copy in getAttribute() and don't warn you not to modify. So...don't modify it. ;) It's pulling backing list from myCurTemplate and shoving into modified. Clone those elements first.