ElispでJavaライクな例外処理を提供するyaxception.elを作りました

これは何?

Emacsは大分前から使っていますが、ようやく最近Elispを書くようになりました。
で、Elispでの例外処理に関して以下の不満を持ちました。

というわけで、自分の作るElispでは、 これらを解決し例外処理を手軽にわかりやすく記述できるようにしたのですが、 最近はel-getなどのパッケージ管理も利用可能になってきているので、 例外処理の機能だけ別の拡張として切り出すことにしました。

Elispの作法などに詳しくないので、果たしてどれほどの利用価値があるかわかりませんが、 とりあえず、自分が使って大分良い感じになってきたので、公開することにしました。

特徴

Javaライクなtry/catch/finally/throw

本拡張を使うと、以下のような感じで記述できるようになります。

(yaxception:$
  (yaxception:try
    (delete-file "not found"))
  (yaxception:catch 'file-error e
    (message "ファイル操作中にエラー : %s" (yaxception:get-text e)))
  (yaxception:catch 'error e
    (message "何かエラー : %s" (yaxception:get-text e))
    (yaxception:throw e))
  (yaxception:finally
    (message "終了したよ")))

カスタムエラー

以下のような感じで、独自のエラーを定義し使えるようになります。

;; file-errorの子のエラーとして、hoge-errorを定義
(yaxception:deferror 'hoge-error
                     'file-error
                     "ファイルをほげしたらエラー - path:[%s] size:[%s]" 'path 'size)

;; 定義したエラーをthrow
(yaxception:throw 'hoge-error
                  :path "c:/hoge.txt"
                  :size (nth 7 (file-attributes "c:/hoge.txt")))

スタックトレース

Elispスタックトレースにあたるものは*Backtrace*バッファに出力されるものだけのようです。
それを出力するためには、debug-on-errorをtにしたりする必要があり、 出力内容も全ての関数やスペシャルフォームなどが羅列され、ちょっと見づらいです。
また、バッファをポップアップしないで、内容だけ欲しかったりします。

なので、もっとわかりやすいスタックトレースを文字列として取得できるようにしました。

以下のような場合、

(defun aaa (aa bb &optional cc) (bbb bb))
(defun bbb (bb) (ccc))
(defun ccc () (replace-regexp-in-string " " "" 'hogege))
(defun xxx (zzz) "xxx")
(defun yyy () "yyy")

(yaxception:$
  (yaxception:try
    (xxx "hoge")
    (yyy)
    (aaa "ABC" "DEF" '("GHI" "JKL")))
  (yaxception:catch 'error e
    (message "%s" (yaxception:get-stack-trace-string e))))

以下が出力されます。

Exception is 'wrong-type-argument'. Wrong type argument: sequencep, hogege
  at replace-regexp-in-string(\" \" \"\" hogege)
  at ccc()
  at bbb(\"DEF\")
  at aaa(\"ABC\" \"DEF\" (\"GHI\" \"JKL\"))
  in yaxception:try

※関数呼び出しのみを羅列しています。
※マクロ呼び出しも羅列したかったんですが、標準添付のマクロやスペシャルフォームとの区別がわかりませんでした。ご存知の方がいらっしゃいましたら、是非ご教授願いたく。

インストール

ソース置き場: https://github.com/aki2o/yaxception

以下の方法があります。

package.elを使う場合

2013/07/19 melpaリポジトリからインストール可能になりました。

el-get.elを使う場合

2013/07/26 インストール可能になりました。ただし、まだmasterにしか登録されていません。

auto-install.elを使う場合

(auto-install-from-url "https://raw.github.com/aki2o/yaxception/master/yaxception.el")

手動の場合

上記URLにアクセスし、yaxception.elをダウンロードしてロードパスの通った場所に配置

Enjoy!!!

その他

  • 詳しい使い方はここにまとめます。
  • 動作確認したEmacsは、GNU Emacs 23.3.1 (i386-mingw-nt5.1.2600) of 2011-08-15 on GNUPACK です。
  • スタックトレースの各要素を個別に取得できる関数とかも欲しいなと思っています。