2

conses を標準のリスト表記ではなく、常にドット ペアとして出力しようとして、最小限の労力でメソッドを次のように再定義しましたprint-object

(defmethod print-object((c cons) str)
  (format str "(~a . ~a)" (car c) (cdr c)))

しかし、その効果は実装によって異なります。

Clozure CL と LispWorks Personal では、結果は私が期待していたものです:

CL-USER 1 > (defmethod print-object((c cons) str)
                (format str "(~a . ~a)" (car c) (cdr c)))
#<STANDARD-METHOD PRINT-OBJECT NIL (CONS . (T . NIL)) 200A45AB>

CL-USER 2 > '(a b c )
(A . (B . (C . NIL)))

一方、SBCL と AllegroCLexpress では、リストの表示方法に変更はありません。

* (defmethod print-object((c cons) str)
     (format str "(~a . ~a)" (car c) (cdr c)))

#<STANDARD-METHOD PRINT-OBJECT (CONS T) {10051EBC53}>
* '(a b c)

(A B C)

したがって、これが言語の仕様のあいまいさによるものなのか、そのような動作が未指定として明示的に宣言されているのか、これが REPL とパッケージとの何らかの相互作用によるものなのか、それとも実装があるのかこの定義に関して正しいものと、正しくない他のものがあります。最後に、SLIME 内でこのような定義を行うと、SLIME 自体が完全に破壊されます。

誰かがそのような違いに光を当て、それが存在する場合、私の目的を達成するための問題の少ない別の方法を提案できますか?

4

2 に答える 2

2

タイトルは少し誤解を招くものです。SBCL には conses のメソッドがありませんprint-object。したがって、再定義することはできません。何らかの理由で、そのようなメソッドを定義できますが、そのプリンターはそれを呼び出しません。

私の知る限り、SBCL はprint-object組み込み型のユーザー定義メソッドをサポートしていません。それらはプリンターによって呼び出されません。プリンター ソースを見ると、TYPE-CASEコンストラクトを使用して、さまざまなデータ型に対してさまざまな印刷関数を呼び出しています。

print-objectSBCL で CLOS クラスのメソッドを定義すると、それらが呼び出されます。

これは ANSI CL と互換性がありませんか? 多分。少なくともprint-objectメソッドを提供しない部分は互換性がないはずです。これは、まだそれらを変更できるという意味ではありません...

PRINT-OBJECTメソッドの観点から定義されているすべて/ほとんど/多くのクラス (組み込みクラスを含む) の印刷を行うと便利でしょうか。はい。

于 2015-08-09T19:30:59.630 に答える