Java処理系でTcl言語のコードを実行するには

 まずはJaclの簡単なサンプルを2つ載せてみます。 Jaclを使ったプログラムを開発したり、実行させたりするには、 環境変数CLASSPATHにインストール時に置かれる2つのJARアーカイブ、 jacl.jarとtcljava.jarを含めておくだけでOKです。

 最初の例は、Tcl変数へのアクセスなどを使わない、ほんとに単に、 Tclコマンドを文字列として解釈実行させ、結果をJava世界で受け取るだけのサンプルです。

import tcl.lang.*;

public class Example1 {

    public static void main(String[] args) throws TclException {
        Interp interp = new Interp(); // インタープリタの作成
        interp.eval("expr 30.1 + 40.25"); // Tclコマンドの実行

        // 実行結果を文字列として取り出す場合
        System.out.println("Result as String: " +
                           interp.getResult().toString());

        // 実行結果を数値として取り出す場合
        TclObject outobj = interp.getResult();
        double value = TclDouble.get(interp, outobj);
        System.out.println("Result as Double: " + String.valueOf(value));

        interp.dispose(); // メモリの解放
    }
}

 コードの説明もそこそこに、まずコンパイルと実行の方法ですが、 これは普通のJavaプログラムの場合と変わりません。 javacコンパイラなどを使って.classファイルを作り、javaコマンドで実行できます。

 それではさっそく、コードの手順を追ってみます。まず、

import tcl.lang.*;
はJaclのお約束と考えてOKです。InterpやTclObjectなどのクラスがこのパッケージ、 tcl.langの中に入っています。

 実際の処理ですが、まず、Tclインタープリタを作ります。 これはtcl.lang.Interpクラスのインスタンスです。

Interp interp = new Interp();

 Tclコマンドの実行は、 インタープリタのevalメソッドで行います。 Tclコマンドの文法エラーなど、 何らかのエラーが発生したら、例外TclException またはそのサブ例外が飛ぶので、例外が飛ばなければ正常終了と考えてOKです。

 コマンドの実行結果をJava世界で受け取る方法ですが、最も簡単には上の例の通り、

String result = interp.getResult().toString();
とする方法です。これはコマンドの実行結果を文字列(java.lang.String) としてJava世界に返すときに使われる最も普遍的な方法です。 が、それ以外に、Javaのdoubleやintとしてコマンドの値を返したい場合には、 初めてTclオブジェクト とゆーものが登場してきます。TclオブジェクトはTclObjectクラスのインスタンスで、
TclObject outobj = interp.getResult();
double value = TclDouble.get(interp, outobj);
このようにしてdouble型として返すことができます。

 さて最後の

interp.dispose();
も、お約束みたいなものです。Jaclのインタープリタは独自にメモリ領域を持っているので、 必要がなくなったらその掃除をさせる処理です。

 もうひとつのサンプルでは、Tcl変数へのアクセスをJava世界から行う処理が加わっています。

import tcl.lang.*;

public class JaclEmbedTester1 {
    public static void main(String[] args)
    throws tcl.lang.TclException {
        Interp interp = new Interp();

        // Tcl変数に値をセットします。
        TclObject obj1 = TclInteger.newInstance(200);
        TclObject obj2 = TclInteger.newInstance(100);

        interp.setVar("var1", obj1, 0);
        interp.setVar("arrvar1", "ABC", obj2, 0);

        // 実行します。
        interp.eval("set var2 [expr $var1 + $arrvar1(ABC)]");
        // 変数の値を取り出して表示します。
        TclObject resultobj = interp.getVar("var2", 0);
        System.out.println("結果=" + resultobj.toString());

        // 今度はコマンドの値として受け取ってみます。
        interp.eval("expr $var1 - $arrvar1(ABC)");
        resultobj = interp.getResult();
        System.out.println("結果=" + resultobj.toString());

        // 終了します。
        interp.dispose();
    }
}

 Java世界の任意の値をTcl変数にセットするには、 TclObjectのサブクラス、 TclInteger やTclStringのクラスメソッド、 newInstanceを使ってオブジェクト(TclObject) を生成し、これをインタープリタのsetVar メソッドでTcl変数にセットします。

TclObject obj1 = TclInteger.newInstance(200);
TclObject obj2 = TclInteger.newInstance(100);

interp.setVar("var1", obj1, 0);
interp.setVar("arrvar1", "ABC", obj2, 0);
setVarメソッドの引数はこのように、Tcl変数がスカラー変数の場合は3個、 配列変数の場合は4個になります。最後の0というのはフラグで、 詳しくはマニュアルをご覧下さい。通常は0でOKです。

 また、何らかのTclコードを実行した後に、 Tcl変数の値の内容をJava世界に返したい場合には、 getVarメソッドを使います。

interp.eval("set var2 [expr $var1 + $arrvar1(ABC)]");
TclObject resultobj = interp.getVar("var2", 0);

拡張レビュー分室 top
(first uploaded 2001/10/17 last updated 2002/08/19, KOUKEN HEIJIMA - MISUMI URANO)