ハッシュテーブル表示

sbcl(1.0.28)では、ハッシュテーブルを表示する際に、テスト関数名と要素数(+ ID)しか出てこない。

> (make-hash-table)
--> #<HASH-TABLE :TEST EQL :COUNT 0 {AFA2A89}>

この(要素の確認し辛さの)ために*1、ついつい連想リストを(代わりに)使うことが多くなってしまうのだが、やはりハッシュを使いたい時(そしてその中身を手軽に見たい時)もあるので、ハッシュ用のprint-objectメソッドを作成した。

このメソッドは、ハッシュの要素数が*print-hash-table-limit*以下の時だけ、その要素を連想リスト的な形式で表示する。

(defvar *print-hash-table-limit* 32)

(defmethod print-object :around ((obj hash-table) stream)
  (if (<= (hash-table-count obj) *print-hash-table-limit*)
      (format stream "#<HT ~{~S~^ ~}>" 
              (loop FOR k BEING THE HASH-KEY USING (hash-value v) OF obj
                    COLLECT `(,k . ,v)))
    (call-next-method)))

> (let ((x (make-hash-table)))
    (setf (gethash :key x) "value")
    x)
--> #<HT (:KEY . "value")>

*1:及び、ハッシュテーブルに初期要素を設定する簡便な記法がデフォルトでは無いために