如何在 common-lisp CLOS 中指向 defgeneric 实例
How to point to a defgeneric instance in common-lisp CLOS
这里是 lisp 初学者。
我知道如何使用函数 find-method 指向特定的方法实例,并且我通过对返回的方法实例使用 slime inspect 看到它有一个插槽 %GENERIC- FUNCTION,但我无法使用它。
(为什么 (slot-value (find-method ...) '%GENERIC-FUNCTION)
告诉我对象中缺少插槽。
那么,我应该如何从 defmethod 对象指向 defgeneric 呢?
我正在使用 sbcl,但是是否有标准化的通用 lisp 方法来实现兼容性?
%GENERIC-FUNCTION
可能指的是您当前包中的符号,而不是内部包中标识插槽的符号。它们具有相同的名称,但属于不同的包。
你做的是CLOS的元对象协议(MOP)相关的,请参考metamodular.com/CLOS-MOP for more information (also, read AMOP)。
我们先加载 closer-mop
:
USER> (ql:quickload :closer-mop)
To load "closer-mop":
Load 1 ASDF system:
closer-mop
; Loading "closer-mop"
(:CLOSER-MOP)
Closer-MOP系统是:
[...] a compatibility layer that rectifies many of the absent or
incorrect CLOS MOP features across a broad range of Common Lisp
implementations.
USER> (find-method #'print-object () (mapcar #'find-class '(vector t)))
#<STANDARD-METHOD COMMON-LISP:PRINT-OBJECT (VECTOR T) {10005605C3}>
(感谢 RainerJoswig 指出专家列表应该包含 class 对象而不是符号)
USER> (closer-mop:class-direct-slots (class-of *))
(#<SB-MOP:STANDARD-DIRECT-SLOT-DEFINITION SB-PCL::%GENERIC-FUNCTION>
#<SB-MOP:STANDARD-DIRECT-SLOT-DEFINITION SB-PCL::QUALIFIERS>
#<SB-MOP:STANDARD-DIRECT-SLOT-DEFINITION SB-PCL::SPECIALIZERS>
#<SB-MOP:STANDARD-DIRECT-SLOT-DEFINITION SB-PCL::LAMBDA-LIST>
#<SB-MOP:STANDARD-DIRECT-SLOT-DEFINITION SB-PCL::%FUNCTION>
#<SB-MOP:STANDARD-DIRECT-SLOT-DEFINITION SB-PCL::%DOCUMENTATION>
#<SB-MOP:STANDARD-DIRECT-SLOT-DEFINITION SB-PCL::SIMPLE-NEXT-METHOD-CALL>)
确实,您需要使用 SB-PCL::%GENERIC-FUNCTION
符号:
USER> (slot-value ** 'SB-PCL::%GENERIC-FUNCTION)
#<STANDARD-GENERIC-FUNCTION COMMON-LISP:PRINT-OBJECT (277)>
(回想一下 *
和 **
是表示在 REPL 中评估的最后一个和倒数第二个值的变量)
备注
这个插槽的SB-PCL::%GENERIC-FUNCTION
符号没有导出(我们需要两个冒号来引用它),它以%
字符开头,这是[=50=的约定]内部(有时危险)符号。你不应该直接使用它;也不推荐直接调用 slot-value
,通常你只需要访问函数。
method-generic-function
相反,您应该使用从 closer-mop
导出的符号以获得更好的兼容性:
(closer-mop:method-generic-function
(find-method #'print-object () (mapcar #'find-class '(vector t))))
这里是 lisp 初学者。
我知道如何使用函数 find-method 指向特定的方法实例,并且我通过对返回的方法实例使用 slime inspect 看到它有一个插槽 %GENERIC- FUNCTION,但我无法使用它。
(为什么 (slot-value (find-method ...) '%GENERIC-FUNCTION)
告诉我对象中缺少插槽。
那么,我应该如何从 defmethod 对象指向 defgeneric 呢? 我正在使用 sbcl,但是是否有标准化的通用 lisp 方法来实现兼容性?
%GENERIC-FUNCTION
可能指的是您当前包中的符号,而不是内部包中标识插槽的符号。它们具有相同的名称,但属于不同的包。
你做的是CLOS的元对象协议(MOP)相关的,请参考metamodular.com/CLOS-MOP for more information (also, read AMOP)。
我们先加载 closer-mop
:
USER> (ql:quickload :closer-mop)
To load "closer-mop":
Load 1 ASDF system:
closer-mop
; Loading "closer-mop"
(:CLOSER-MOP)
Closer-MOP系统是:
[...] a compatibility layer that rectifies many of the absent or incorrect CLOS MOP features across a broad range of Common Lisp implementations.
USER> (find-method #'print-object () (mapcar #'find-class '(vector t)))
#<STANDARD-METHOD COMMON-LISP:PRINT-OBJECT (VECTOR T) {10005605C3}>
(感谢 RainerJoswig 指出专家列表应该包含 class 对象而不是符号)
USER> (closer-mop:class-direct-slots (class-of *))
(#<SB-MOP:STANDARD-DIRECT-SLOT-DEFINITION SB-PCL::%GENERIC-FUNCTION>
#<SB-MOP:STANDARD-DIRECT-SLOT-DEFINITION SB-PCL::QUALIFIERS>
#<SB-MOP:STANDARD-DIRECT-SLOT-DEFINITION SB-PCL::SPECIALIZERS>
#<SB-MOP:STANDARD-DIRECT-SLOT-DEFINITION SB-PCL::LAMBDA-LIST>
#<SB-MOP:STANDARD-DIRECT-SLOT-DEFINITION SB-PCL::%FUNCTION>
#<SB-MOP:STANDARD-DIRECT-SLOT-DEFINITION SB-PCL::%DOCUMENTATION>
#<SB-MOP:STANDARD-DIRECT-SLOT-DEFINITION SB-PCL::SIMPLE-NEXT-METHOD-CALL>)
确实,您需要使用 SB-PCL::%GENERIC-FUNCTION
符号:
USER> (slot-value ** 'SB-PCL::%GENERIC-FUNCTION)
#<STANDARD-GENERIC-FUNCTION COMMON-LISP:PRINT-OBJECT (277)>
(回想一下 *
和 **
是表示在 REPL 中评估的最后一个和倒数第二个值的变量)
备注
这个插槽的SB-PCL::%GENERIC-FUNCTION
符号没有导出(我们需要两个冒号来引用它),它以%
字符开头,这是[=50=的约定]内部(有时危险)符号。你不应该直接使用它;也不推荐直接调用 slot-value
,通常你只需要访问函数。
method-generic-function
相反,您应该使用从 closer-mop
导出的符号以获得更好的兼容性:
(closer-mop:method-generic-function
(find-method #'print-object () (mapcar #'find-class '(vector t))))