読者です 読者をやめる 読者になる 読者になる

リーダーマクロで非公開シンボルの参照を簡略化する @ テスト

#:g1: リーダーマクロでシンボルの略記をする」を読んでいて、こういうリーダーマクロの使い方することあるなと思ったので投稿。大した用途ではないですが…。

こんなことはないでしょうか。

  • インタフェースとしては不要なので公開はしたくない補助関数がある
  • とはいえ、それなりに面倒な関数なので単体でテストしておかないと不安がある
  • しかも、それなりに数があるので、毎回<package>::<symbol>と書くのも面倒くさい

Domain Specific LanguageDSL)まがいの大き目なマクロを書いていると良くある…のかもしれません。

自身の例ではkv-kneaderというライブラリ*1がありました。src/kneader.lispという実質120行程度のファイルがありますが、公開しているのはkneadという15行のマクロひとつで、後はこのマクロのための補助関数(マクロ)です。

こうなってくると補助関数もテストしておかないと落ち着かないのですが、都度kv-kneader.kneader::parse-a-key-descriptionなどと書くと見るのも辛いです。

ようやく本題ですが、こんなときに$:parse-a-key-descriptionと書けると幸せかと思い、こんなリーダーマクロを書きました。

(eval-when (:compile-toplevel :load-toplevel :execute)
  (make-dispatch-macro-character #\$)
  (set-dispatch-macro-character
   #\$ #\:
   #'(lambda (stream &rest rest)
       (declare (ignore rest))
       (intern (symbol-name (read stream nil))
               (regex-replace "-TEST" (package-name *package*) "")))))

利用にあたっては、<hoge>.<fuga>というパッケージのテストは<hoge>-test.<fuga>というパッケージで行うという前提が必要です。このとき、<hoge>-test.<fuga>パッケージ内で$:piyoとすると、"-test"がとれて<hoge>.<fuga>::piyoというシンボルになります*2

kv-kneader/kneader.lisp at master · eshamster/kv-kneader · GitHubが件のテストファイルですが、これの$:が全部kv-kneader.kneader::になっていたら、中々気が狂いそうです。

*1:詳細略。key-valueなデータをゴネゴネするためのライブラリです。そのうち記事にしようと思って忘れていました…

*2:正規表現が手抜きなので、<hoge>の中に"-test"が含まれるとそちらが取れてしまいますが、目をつむっています