[Clojure]JSwatでデバッグする
ClojureでGUIデバッグ
さて、みなさんはclojureではどうやってデバッグしてますか? 世間ではswank-clojureをつかったり、Clojure Debugging Toolkitをつかったり、 JSwatをつかうようです。 今回はJSwatを使ってClojureのデバッグを行なってみます。
JSwatとは
JSwatとは、オープンソースのJava用GUIデバッガです。NetBeansにも組み込まれていて、デバッグに便利なさまざまな機能をもっています。 私はあまり詳しく知らなかったのですが、昔からよく使われているようです。
環境
今回使用した動作環境は以下のとおりです。
- OS : MacOS X 10.7.4
- Java : 1.7.0_14
- Clojure : 1.5.1
- Leiningen : 2.0.0
- JSwat : jswat-2013.1.zip
LeiningenはClojure用ビルドツールで、Clojure開発には必須のツールです。今回使用するのでインストールしておきましょう。 また、JSwatも自分の環境にあったファイルをダウンロードし、インストールしておいてください。
Clojureプログラムをデバッグしてみる
Leiningenでプロジェクト作成
まずはLeiningenでプロジェクトを作成します。
% lein new jswatdebug
プロジェクトファイルを修正
jswatdebug/project.cljファイルを下記のように修正します。 Clojure 1.5を使用するようにと、:jvm-opts でデバッグ用設定を追記しました。
(defproject jswatdebug "0.1.0-SNAPSHOT" :description "FIXME: write description" :url "http://example.com/FIXME" :license {:name "Eclipse Public License" :url "http://www.eclipse.org/legal/epl-v10.html"} :dependencies [[org.clojure/clojure "1.5.1"]] :jvm-opts [ "-server" "-Xms128M" "-Xmx256M" "-Xdebug" "-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=9900"])
プロジェクトファイルを修正したらdepsで依存ファイルを更新しておきます。
% cd jswatdebug % lein deps
ソースファイルを修正
デバッグ対象のプログラムファイルを修正しましょう。 jswatdebug/src/jswatdebug/core.cljに下記関数を追加します。
(defn greet ([] (str "hello,someone.")) ([name] (str "hello," name)))
REPLを起動
コンソールでREPLを起動しましょう。leinからREPLを起動することで、 leinプロジェクトで使用するライブラリのクラスパスを全て通した状態でREPLを起動できます。 なお、Sublime2 Textを使用している場合、SublimeREPLを使ってREPLを起動することもできます。
% lein repl Listening for transport dt_socket at address: 9900 nREPL server started on port 55403 REPL-y 0.1.9 Clojure 1.5.1 user=>
REPLを起動すると、デバッグ用ポートが9900番で待ち受けていることがわかります。
JSwat起動
JSwatを起動し、メニューからSession > Attachと選択し、デバッガ用ポートへ接続するための設定を記述します。 Hostはlocalhost、Portは9900を指定しましょう。
Attachしたら、対象のファイルを開きます。ファイル > ファイルを開くを選択し、src/jswatdebug/core.cljファイルをひらきましょう。 ファイルを開いたら、下記画像でハイライトされている行にカーソルを持って行き、右クリックで「Toggle Breakpoint」を選択します。 これでこの行にブレークポイントが設定されます。
REPLからプログラム実行
では、jswatdebug.coreをuseし、greet関数を使用してみてください。 REPLでgreet関数を呼び出すと、下記画像のようにブレークポイントで停止し、ステップ実行をしたり変数の中身を確認することができます。
user=> (use 'jswatdebug.core) (use 'jswatdebug.core) nil user=> (greet 'taro') (greet 'taro') "hello,taro'"