[Clojure]JSwatでデバッグする

2013.03.20

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

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を指定しましょう。
img1

Attachしたら、対象のファイルを開きます。ファイル > ファイルを開くを選択し、src/jswatdebug/core.cljファイルをひらきましょう。
ファイルを開いたら、下記画像でハイライトされている行にカーソルを持って行き、右クリックで「Toggle Breakpoint」を選択します。
これでこの行にブレークポイントが設定されます。
img2

REPLからプログラム実行

では、jswatdebug.coreをuseし、greet関数を使用してみてください。
REPLでgreet関数を呼び出すと、下記画像のようにブレークポイントで停止し、ステップ実行をしたり変数の中身を確認することができます。

user=> (use 'jswatdebug.core)
(use 'jswatdebug.core)
nil

user=> (greet 'taro')
(greet 'taro')
"hello,taro'"

img3