Programming Nuts

Programming or Configuration?

The line between configuration and programming is subtle. At one moment we may think we are settled down with the extensible markup language. We lean back comfortably and proudly enjoy the declarative elegance of our Ant build file and our xml configuration file.

But wait, what is that sound? Is that the ghost of programming and logic lurking there? I do hear his familiar scream that's been torturing me since forever.

Why do we still want "if-else"? Why do we still think in the "this executes, then the next step runs" way? Isn't that what we've been trying to escape from?

Don't look at me. I have no answer. My own response is tragic: I gave in.

Rather than trying to smother the need of programming, Nuts enables programming in XML. You don't have to use it if you are braver than me to fight with the temptation of programming. But this is my story of how I surrendered with Nuts.

Programming in Nuts

In the Extending Nuts section, I introduced the way of writing customized tag using Java class, pretty much the same idea as how Ant supports custom tasks.

If that does't bother you too much, we also presented the <sequence> tag in the Advanced Tags section, which is used to do "sequencing"; We have <local> tag to declare local variables; In the jfun.yan.xml.nuts.optional package, we stacked around 20 custom tags supporting if-else, switch-case, comparison, print, assertion, etc.

When I was testing Nuts, I needed to write various components, to come up with all kinds of wierd ways of wiring them up. And I need to verify that the result of the wiring is as expected.

If I don't program in Nuts, The "assertEqual", "assertSame" logic will have to be put into Java code using JUnit. But the problem is: the way of the wiring and the result of the wiring are closely related and coupled to each other. It's just a pain to have to maintain them separately.

Let's say I need to wire up an object and an array that contains this object. I also need to let the object refer back to the array so that I get a mutual dependency. Doing it Java, the code will be:

PointBack[] arr = new PointBack[1];
PointBack pb = new PointBack(arr);
arr[0] = pb;
assertSame(pb.getArray(), arr);
assertTrue(pb.getArray() instanceof PointBack[]);

And my Nuts code is:

<module name="test nuts">
<nut name="assertSame" class="jfun.yan.xml.nuts.optional.AssertSameNut"/>
<nut name="assertEqual" class="jfun.yan.xml.nuts.optional.AssertEqualNut"/>
<nut name="at" class="jfun.yan.xml.nuts.optional.SubscriptNut"/>
<nut name="instanceof" class="jfun.yan.xml.nuts.optional.InstanceOfNut"/>
<body>
  <sequence id="test case for array mutual dependency">
    <local>
      <array id="arr" type="PointBack[]">
        <ctor class="PointBack">
          <arg ind="0" val="$arr"/>
        </ctor>
      </array>
    </local>
    <getter name="array" var="inner_array">
      <at component="$arr" ind="0"/>
    </getter>
    <assertSame val1="$arr" val2="$inner_array"/>
    <assertEqual>
      <value val="true" type="boolean"/>
      <instanceof class="PointBack[]" component="$inner_array"/>
    </assertEqual>
  </sequence>
</body>
</module>

It's of course not encouraged to do a lot of programming in your configuration file, but when you have to have it, there you go.


Created by benyu
On Sat Nov 12 17:29:38 CST 2005
Using TimTam

Labels

 
(None)