...
Note |
---|
This article probably should be merged in with Group Files. Also, one on some points it seemed out-of-date - I've made annotations in red where I think this occurs. - Graham Wideman 2009-05-21 |
...
The supergroup has a bold definition but the subgroup does not. Referencing $name:bold()$
from a template in the subgroup works because subgroup looks into its supergroup if it a referenced template is not found in the subgroup..
You A template in a subgroup may override templatesa template inhererited from a supergroup:
Java | Code Block |
---|
supergroup.defineTemplate("bold", "<b>$it$</b>");
subgroup.defineTemplate("bold", "<strong>$it$</strong>");
|
|
---|
C# | Code Block |
---|
supergroup.DefineTemplate("bold", "<b>$it$</b>");
subgroup.DefineTemplate("bold", "<strong>$it$</strong>");
|
|
---|
Python | Code Block |
---|
supergroup.defineTemplate("bold", "<b>$it$</b>");
subgroup.defineTemplate("bold", "<strong>$it$</strong>");
|
|
---|
And you a template in a subgroup may refer to a template in a supergroup via super.
template()
:
Java | Code Block |
---|
StringTemplateGroup group = new StringTemplateGroup(...);
StringTemplateGroup subGroup = new StringTemplateGroup(...);
subGroup.setSuperGroup(group);
group.defineTemplate("page", "$font()$:text");
group.defineTemplate("font", "Helvetica");
subGroup.defineTemplate("font", "$super.font()$ and Times");
StringTemplate st = subGroup.getInstanceOf("page");
|
|
---|
C# | Code Block |
---|
StringTemplateGroup group = new StringTemplateGroup(...);
StringTemplateGroup subGroup = new StringTemplateGroup(...);
subGroup.SuperGroup = group;
group.DefineTemplate("page", "$font()$:text");
group.DefineTemplate("font", "Helvetica");
subGroup.DefineTemplate("font", "$super.font()$ and Times");
StringTemplate st = subGroup.GetInstanceOf("page");
|
|
---|
Python | Code Block |
---|
group = stringtemplate3.StringTemplateGroup(...)
subGroup = stringtemplate3.StringTemplateGroup(...)
subGroup.setSuperGroup(group)
group.defineTemplate("page", "$font()$:text")
group.defineTemplate("font", "Helvetica")
subGroup.defineTemplate("font", "$super.font()$ and Times")
st = subGroup.getInstanceOf("page")
|
|
---|
The string expression st.ToString()
results in "Helvetica and Times:text
".
Just like object-oriented programming languages, StringTemplate
has polymorphism. That is, template names are looked up dynamically relative to the invoking templates template's group.
The classic demonstration of dynamic message sends, for example, would be the following example (this catches my students all the time):
Java | Code Block |
---|
class A {
public void page() {bold();}
public void bold() {System.out.println("A.bold");}
}
class B extends A {
public void bold() {System.out.println("B.bold");}
}
...
A a = new B();
a.page();
|
|
---|
C# | Code Block |
---|
class A {
public void page() {bold();}
override public void bold() {Console.Out.WriteLine("A.bold");}
}
class B : A {
virtual public void bold() {Console.Out.WriteLine("B.bold");}
}
...
...
A a = new B();
a.page();
|
|
---|
This prints "B.bold
" not "A.bold
" because the receiver determines how to answer a message not the type of the variable. So, I have created a B
object meaning that any message, such as bold()
, invoked will first look in class B
for bold()
.
Similarly, a template's group determines where it starts looking for a template. In this case, both super and sub groups define a bold
template mirroring the code above. Because I create template st
as a member of the subGroup
and , any reference to bold
starts looking (say while processing st.ToString()
) prompts StringTemplate to start looking for the bold
template in subGroup
, even though bold
is referenced via the page
template which is the template referring to bold
a member of the supergroup..
Java | Code Block |
---|
StringTemplateGroup group = new StringTemplateGroup("super");
StringTemplateGroup subGroup = new StringTemplateGroup("sub");
subGroup.setSuperGroup(group);
group.defineTemplate("bold", "<b>$it$</b>");
group.defineTemplate("page", "$name:bold()$");
subGroup.defineTemplate("bold", "<strong>$it$</strong>");
StringTemplate st = subGroup.getInstanceOf("page");
st.setAttribute("name", "Ter");
String expecting = "<strong>Ter</strong>";
|
|
---|
C# | Code Block |
---|
StringTemplateGroup group = new StringTemplateGroup("super");
StringTemplateGroup subGroup = new StringTemplateGroup("sub");
subGroup.SuperGroup = group;
group.DefineTemplate("bold", "<b>$it$</b>");
group.DefineTemplate("page", "$name:bold()$");
subGroup.DefineTemplate("bold", "<strong>$it$</strong>");
StringTemplate st = subGroup.GetInstanceOf("page");
st.SetAttribute("name", "Ter");
string expecting = "<strong>Ter</strong>";
|
|
---|
Python | Code Block |
---|
group = stringtemplate3.StringTemplateGroup("super")
subGroup = stringtemplate3.StringTemplateGroup("sub", superGroup=group)
group.defineTemplate("bold", "<b>$it$</b>")
group.defineTemplate("page", "$name:bold()$")
subGroup.defineTemplate("bold", "<strong>$it$</strong>")
st = subGroup.getInstanceOf("page")
st["name"] = "Ter"
expecting = "<strong>Ter</strong>"
|
|
---|
StringTemplate
group maps also inherit. If an attribute reference is not found, StringTemplate
looks for a map in its group with that name. If not found, the super group is checked.
See more extensive details regarding template and attribute lookup here: Template and attribute lookup rules