#:g1: asdf-package-systemの紹介

Posted 2014-05-08 15:00:00 GMT

(LISP Library 365参加エントリ)

 LISP Library 365 の129日目です。

asdf-package-systemとはなにか

 asdf-package-systemは、Francois-Rene Rideau(fare)氏作のASDFのsystemのソースファイル名とパッケージ名を合致させるコーディングスタイルのためのユーティリティです。

パッケージ情報

パッケージ名asdf-package-system
Quicklisp
CLiKihttp://cliki.net/asdf-package-system
Quickdocshttp://quickdocs.org/asdf-package-system

インストール方法

(ql:quickload :asdf-package-system)

試してみる

 どんな関数があるかは、Quickdocsで確認できます。

 最近ASDFを使っていて、やたらasdf/defsystemとか、asdf/なんとかというパッケージが増えたなーと思っていましたが、どうもASDF3からソースファイル名とパッケージ名が連動しているスタイルで書き始めたからのようです。

 具体的な書き方はREADMEに詳しいですが、ディレクトリ階層が1階層のシンプルな場合の簡単な例を説明してみます。

という2つファイルを主な構成要素とする、asdf-pkgsys-testというsystemを定義する場合、下記のような感じになるようです。

all.lisp
;;;; asdf-pkgsys-test.lisp -*- Mode: Lisp;-*- 

(defpackage :asdf-pkgsys-test/all
  (:use :cl)
  (:nicknames :asdf-pkgsys-test)
  (:export :hello))

(cl:in-package :asdf-pkgsys-test/all)

(defun hello () "hello")

;;; *EOF*

まず、メインのファイルですが、ファイル名にmainでもallでもメインっぽい好きな名前を付けることになります。そしてパッケージも対応する名前に。その上でニックネームを全体のパッケージ名とするようです〈逆でも良いのかも〉。

test.lisp
;;;; test.lisp -*- Mode: Lisp;-*- 

(defpackage :asdf-pkgsys-test/test
  (:use :cl :5am :asdf-pkgsys-test/all))

(cl:in-package :asdf-pkgsys-test/test) (in-suite* :asdf-pkgsys-test/test)

(test hello (is (string= "hello" (hello))))

;;; *EOF*

次にテストのファイルですが、testという名前なので、パッケージはasdf-pkgsys-test/testという名前になります。

asdf-pkgsys-test.asd
;;;; asdf-pkgsys-test.asd -*- Mode: Lisp;-*- 

(cl:in-package :asdf)

(defsystem :asdf-pkgsys-test :class :package-inferred-system :depends-on (:asdf-pkgsys-test/all) :in-order-to ((test-op (load-op :asdf-pkgsys-test/test))) :perform (test-op (o c) (let ((result (symbol-call :5am :run :asdf-pkgsys-test/test))) (symbol-call :5am :explain! result) (or (symbol-call :5am :results-status result) (error "test-op failed")))))

(register-system-packages :fiveam '(:5am))

;;; *EOF*

そして問題のasdファイルですが、:class :package-inferred-system を指定して、:depends-onには、:asdf-pkgsys-test/allも記載します。
その他、通常と大体同じです。上記の例では、fiveamをテストフレームワークとして利用していますが、systemの名前が一致しない場合〈パッケージがニックネームで記述されたりetc〉にregister-system-packagesの記述が必要になるようです。

 さらに、このスタイルだと、シンボルをまとめて、exportしなおしたりしたくなりますが、その辺りを支援してくれるマクロもuiop:define-packageとして定義されています。
また上記では、1階層のみでしたが、階層が深くなれば、foo/bar/bazのように書いて行くことになります。

まとめ

 今回は、asdf-package-systemを紹介してみました。
どうもこのスタイルはあまり好きになれないのですが、馴れれば便利なのかもと思ったり思わなかったりです。とりあえず、現状はSLIMEの補完で変なものが出てきて面倒なのは確か。
代表パッケージのシンボルをサブパッケージが継承しているのではなく、サブパッケージのシンボルを代表パッケージがexportし直しているのが原因なのですが、この辺りをどうにかして欲しいと思ったりです。

comments powered by Disqus