专门用于符号的 Common Lisp 方法 - 不能在其他包中使用,不能导出?
Common Lisp method specialized on symbol - can't use in other packages, can't export?
我一直在研究 Practical Common Lisp 的 binary parser project,并试图拆分泛型(class 和宏定义)和细节(特定类型和方法实现)到不同的包中。因此,我有以下代码:
在packages.lisp中:
(defpackage :binparse
(:use :cl)
(:export :read-value :write-value :read-object :write-object
:current-binary-object :parent-of-type :define-binary-class
:define-tagged-binary-class :define-binary-type))
(defpackage :primitives
(:use :cl :binparse))
在binparse.lisp中:
(defgeneric read-value (type stream &key)
(:documentation "Read a value of the given type from the stream."))
(defgeneric write-value (type stream value &key)
(:documentation "Write the value of the given type to the stream."))
(defmacro define-binary-type (name (&rest args) &body spec) ...) ; calls defmethod for read-value and write-value, specialized on (type (eql ,name))
在primitives.lisp中:
(define-binary-type u1 () ...) ; defines reader and writer spec for 1-byte unsigned int, specialized on (type (eql 'u1))
我无法确定如何从 primitives
中正确导出方法实现。如果我 不 执行任何超出上面 packages
中定义的导出,那么我可以执行以下操作:
CL-USER> (binparse:read-value primitives::'u1 *testfile*) ; succeeds
CL-USER> (binparse:read-value primitives::u1 *testfile*) ; fails, unbound variable U1
CL-USER> (binparse:read-value 'u1 *testfile*); fails, class-not-found u1
PRIMITIVES> (read-value 'u1 *testfile*) ; succeeds
但是,我无法弄清楚如何从 primitives
导出 'u1
(或用作方法说明符的其他符号)以避免双冒号或可能允许导入其他包。在 defpackage
中包含 (:export :u1)
无效。已经在 primitives
中时也不会调用 (export 'u1)
。与双冒号不同,单冒号不允许使用最初有效的 ::'u1
。
从 PCL 扩展项目似乎是一件相当正常的事情,将包中的基本二进制解析器代码定义为在其他地方用于特定扩展,但我不知道该怎么做,也没有发现其他人询问它。
弄明白了:如果我在 packages.lisp
中 (:export #:u1)
,我可以使用 (binparse:read-value 'primitives:u1 *testfile*)
获得方法的正确特化。因此,引号位于 之前 符号的 package-name 部分。
我一直在研究 Practical Common Lisp 的 binary parser project,并试图拆分泛型(class 和宏定义)和细节(特定类型和方法实现)到不同的包中。因此,我有以下代码:
在packages.lisp中:
(defpackage :binparse
(:use :cl)
(:export :read-value :write-value :read-object :write-object
:current-binary-object :parent-of-type :define-binary-class
:define-tagged-binary-class :define-binary-type))
(defpackage :primitives
(:use :cl :binparse))
在binparse.lisp中:
(defgeneric read-value (type stream &key)
(:documentation "Read a value of the given type from the stream."))
(defgeneric write-value (type stream value &key)
(:documentation "Write the value of the given type to the stream."))
(defmacro define-binary-type (name (&rest args) &body spec) ...) ; calls defmethod for read-value and write-value, specialized on (type (eql ,name))
在primitives.lisp中:
(define-binary-type u1 () ...) ; defines reader and writer spec for 1-byte unsigned int, specialized on (type (eql 'u1))
我无法确定如何从 primitives
中正确导出方法实现。如果我 不 执行任何超出上面 packages
中定义的导出,那么我可以执行以下操作:
CL-USER> (binparse:read-value primitives::'u1 *testfile*) ; succeeds
CL-USER> (binparse:read-value primitives::u1 *testfile*) ; fails, unbound variable U1
CL-USER> (binparse:read-value 'u1 *testfile*); fails, class-not-found u1
PRIMITIVES> (read-value 'u1 *testfile*) ; succeeds
但是,我无法弄清楚如何从 primitives
导出 'u1
(或用作方法说明符的其他符号)以避免双冒号或可能允许导入其他包。在 defpackage
中包含 (:export :u1)
无效。已经在 primitives
中时也不会调用 (export 'u1)
。与双冒号不同,单冒号不允许使用最初有效的 ::'u1
。
从 PCL 扩展项目似乎是一件相当正常的事情,将包中的基本二进制解析器代码定义为在其他地方用于特定扩展,但我不知道该怎么做,也没有发现其他人询问它。
弄明白了:如果我在 packages.lisp
中 (:export #:u1)
,我可以使用 (binparse:read-value 'primitives:u1 *testfile*)
获得方法的正确特化。因此,引号位于 之前 符号的 package-name 部分。