Thursday, October 24, 2013

How to get TCL "huddle" from inside JACL

JACL can parse the "old TCL" dict format.

TCL has a very nice library to deal with this kind of format, called Huddle. Huddle is part of the tcllib package and, specifically, a very useful command called "compile" was added after version 1.11 (I don't know exactly which version, but it's before 1.15).

Huddle relies on another TCL library called "dict". This library was incorporated into the language since TCL 8.5.

The problem here now is Jacl, the java TCL interpreter. It was not build with "dict" support, so you need a patch to include the "dict" command (http://sourceforge.net/p/tcljava/patches/15).

Finally, jacl identifies itself as "less than TCL 8.5", and the first thing that huddle checks is if it needs "dict". See $PATHTO/tcllib1.15/yaml/huddle.tcl

right in the beginning, you'll see
if { [package vcompare [package provide Tcl] 8.5] < 0 } {
    package require dict
}

to avoid the annoying message of "Exception in thread "main" tcl.lang.TclException:
can't find package dict", you MUST comment this part of the huddle code, so it will be just like this

if { [package vcompare [package provide Tcl] 8.5] < 0 } {
#    package require dict
}

Then you'll be able to write java code just like this

        String x = "{username {root}} {shadow {x}}";
        interp.eval("lappend auto_path \"LIB\"".replaceAll("LIB", "/PATH/TO/tcllib1.15/"));     
        interp.eval("package require huddle");
        interp.eval("set x [ huddle compile { list { dict } }  {"+x+"} ]");
        interp.eval("set i [ huddle jsondump $x ]");
        String json = interp.getVar("i", 0).toString();
        System.out.println(json);

to get this kind of result

[
  {"username": "root"},
  {"shadow": "x"}
]

ps. Tom kindly answered my email at the tcl/java users mailing list, suggesting a cleaner and more elegant solution for this, that I'll certainly evaluate. Thanks Tom!

No comments:

Post a Comment