On second thought, null and missing are same thing

I've done a lot of thinking about this and I believe I made a mistake in the final ST 3.2.1 version before my current rebuild (v4). It's too confusing, and makes the code too complex, to distinguish between missing and present but null. There is huge history with ST too suggests that it seems to work okay treating a missing attribute and a null attribute as the same thing (i.e., not there). We have the null option that lets us say what to replace null with. there are a few corner cases that I've cleaned up, but ST ain't broke so I don't think I will "fix" this part. Has the advantage of being backward compatible, which will be important when I move onto rebuilding the front end of ANTLR v3 so that it does not use ANTLR v2.

Here are two of my unit tests. The difference you will notice that adding (setAttribute) null stores a null the value attribute in the attributes table. This is consistent than when I pass an array of size 1 with a null element.

    @Test public void testNullValueAndNullOption() throws Exception {
        STGroup group = new STGroup();
        group.defineTemplate("test", "<name; null=\"n/a\">");
        ST st = group.getInstanceOf("test");
        st.add("name", null);
        String expected = "n/a";
        String result = st.render();
        assertEquals(expected, result);
    }

Here it uses the null option because name is missing (same as null value attribute)

    @Test public void testMissingValueAndNullOption() throws Exception {
        STGroup group = new STGroup();
        group.defineTemplate("test", "<name; null=\"n/a\">");
        ST st = group.getInstanceOf("test");
        String expected = "n/a";
        String result = st.render();
        assertEquals(expected, result);
    }

The use case that I had for "missing" being important I realize is now a flaw in my thinking. filtering should be done in the model and not the view so my use case was an abuse case (smile)

When I yanked out the code that handled all of this missing versus null crap, it became much simpler and easier to understand + faster etc...