从泛型函数中删除一个方法
Remove one method from a generic function
我已将以下方法添加到通用函数 speak
但现在想在 REPL 中删除此特定方法而不删除通用函数的其余方法。
(defmethod speak :around ((c courtier) string) ; [1]
(format t "Does the King believe that ~A?" string)
(if (eql (read) 'yes)
(if (next-method-p) (call-next-method)) ; [2]
(format t "Indeed, it is a preposterous idea.~%"))
'bow)
[1] The :around method replaces the primary method for the type.
[2] Then it decides whether to call the primary method or not.
函数 remove-method
的 documentation link 没有示例,我不知道引用上面实际 :around
方法的语法是什么。
(remove-method #'speak)
TOO FEW ARGUMENTS
(remove-method #'speak :around)
NO-APPLICABLE-METHOD
来自文档:
remove-method generic-function method
它需要一个通用函数对象和一个方法对象作为参数。
可以通过find-method
找到方法。
CL-USER 39 > (find-method #'speak
(list :around)
(list (find-class 'courtier) (find-class t)))
#<STANDARD-METHOD SPEAK (:AROUND) (COURTIER T) 42001285EB>
CL-USER 40 > (remove-method #'speak
(find-method #'speak
(list :around)
(list (find-class 'courtier)
(find-class t))))
#<STANDARD-GENERIC-FUNCTION SPEAK 422000A68C>
另请注意,良好的 Lisp 开发环境可能还允许在编辑器或检查器中删除方法。
请注意,在 Lisp 侦听器中,不需要像上面那样调用两次 find-method
。变量 *
包含最后一个结果。
CL-USER 43 > (find-method #'speak
(list :around)
(list (find-class 'courtier)
(find-class t)))
#<STANDARD-METHOD SPEAK (:AROUND) (COURTIER T) 4200150DEB>
CL-USER 44 > (remove-method #'speak *)
#<STANDARD-GENERIC-FUNCTION SPEAK 422000A68C>
这是另一个在 GNU Emacs 中使用 SLIME 的交互示例,并启用了 SLIME 的 演示 功能。 presentation 是 Lisp 输出,它保持打印对象和生成文本之间的联系。
调用find-method
函数。它 returns 方法。这里我们使用 presentations
,它保持文本和 Lisp 对象之间的联系。输出显示为红色,鼠标敏感。将鼠标移动到红色返回对象上将添加交互选项。
现在键入 (remove-method #'speak
,然后在红色输出上单击鼠标中键(或 SLIME 配置使用的任何内容):演示文稿(文本和连接的对象)将被复制到该行。输入 )
并输入表格。 SLIME 实际上已经构建了一个包含真实对象而不是文本表示的列表,然后。
这就是 repls 在 Symbolics Lisp Machine 和 CLIM / McCLIM 中的工作方式...
如果将 GNU Emacs 与 SLIME 一起使用,您还可以使用 slime-inspector。例如定义泛型函数 foo
和两个方法:
USER> (defgeneric foo (x))
#<STANDARD-GENERIC-FUNCTION FOO (0)>
USER> (defmethod foo ((x string)) (length x))
#<STANDARD-METHOD FOO (STRING) {100B4D7E23}>
USER> (defmethod foo ((x integer)) x)
#<STANDARD-METHOD FOO (INTEGER) {100C355843}>
您有两个主要选项可以进入检查器:
在 REPL 中,键入 #'foo
以便打印通用方法的表示对象:
USER> #'foo
#<STANDARD-GENERIC-FUNCTION FOO (0)>
右键单击 演示文稿(#<...>
内的任意位置)和 select Inspect
,或者将光标放在演示文稿中并按 C-c C-v TAB (slime-inspect-presentation-at-point
).
从源文件中,输入 slime-inspect
、a.k.a。 C-c I,输入#'foo
.
在这两种情况下,您都会看到与此类似的视图:
#<STANDARD-GENERIC-FUNCTION {505A9A2B}>
--------------------
Name: FOO
Arguments: (X)
Method class: #<STANDARD-CLASS COMMON-LISP:STANDARD-METHOD>
Method combination: #<SB-PCL::STANDARD-METHOD-COMBINATION STANDARD () {1000214003}>
Methods:
(INTEGER) [remove method]
(STRING) [remove method]
(....)
每个 [remove method]
文本实际上是一个按钮,单击或按 Return 可以从通用函数中删除关联的方法。
我已将以下方法添加到通用函数 speak
但现在想在 REPL 中删除此特定方法而不删除通用函数的其余方法。
(defmethod speak :around ((c courtier) string) ; [1]
(format t "Does the King believe that ~A?" string)
(if (eql (read) 'yes)
(if (next-method-p) (call-next-method)) ; [2]
(format t "Indeed, it is a preposterous idea.~%"))
'bow)
[1] The :around method replaces the primary method for the type.
[2] Then it decides whether to call the primary method or not.
函数 remove-method
的 documentation link 没有示例,我不知道引用上面实际 :around
方法的语法是什么。
(remove-method #'speak)
TOO FEW ARGUMENTS
(remove-method #'speak :around)
NO-APPLICABLE-METHOD
来自文档:
remove-method generic-function method
它需要一个通用函数对象和一个方法对象作为参数。
可以通过find-method
找到方法。
CL-USER 39 > (find-method #'speak
(list :around)
(list (find-class 'courtier) (find-class t)))
#<STANDARD-METHOD SPEAK (:AROUND) (COURTIER T) 42001285EB>
CL-USER 40 > (remove-method #'speak
(find-method #'speak
(list :around)
(list (find-class 'courtier)
(find-class t))))
#<STANDARD-GENERIC-FUNCTION SPEAK 422000A68C>
另请注意,良好的 Lisp 开发环境可能还允许在编辑器或检查器中删除方法。
请注意,在 Lisp 侦听器中,不需要像上面那样调用两次 find-method
。变量 *
包含最后一个结果。
CL-USER 43 > (find-method #'speak
(list :around)
(list (find-class 'courtier)
(find-class t)))
#<STANDARD-METHOD SPEAK (:AROUND) (COURTIER T) 4200150DEB>
CL-USER 44 > (remove-method #'speak *)
#<STANDARD-GENERIC-FUNCTION SPEAK 422000A68C>
这是另一个在 GNU Emacs 中使用 SLIME 的交互示例,并启用了 SLIME 的 演示 功能。 presentation 是 Lisp 输出,它保持打印对象和生成文本之间的联系。
调用find-method
函数。它 returns 方法。这里我们使用 presentations
,它保持文本和 Lisp 对象之间的联系。输出显示为红色,鼠标敏感。将鼠标移动到红色返回对象上将添加交互选项。
现在键入 (remove-method #'speak
,然后在红色输出上单击鼠标中键(或 SLIME 配置使用的任何内容):演示文稿(文本和连接的对象)将被复制到该行。输入 )
并输入表格。 SLIME 实际上已经构建了一个包含真实对象而不是文本表示的列表,然后。
这就是 repls 在 Symbolics Lisp Machine 和 CLIM / McCLIM 中的工作方式...
如果将 GNU Emacs 与 SLIME 一起使用,您还可以使用 slime-inspector。例如定义泛型函数 foo
和两个方法:
USER> (defgeneric foo (x))
#<STANDARD-GENERIC-FUNCTION FOO (0)>
USER> (defmethod foo ((x string)) (length x))
#<STANDARD-METHOD FOO (STRING) {100B4D7E23}>
USER> (defmethod foo ((x integer)) x)
#<STANDARD-METHOD FOO (INTEGER) {100C355843}>
您有两个主要选项可以进入检查器:
在 REPL 中,键入
#'foo
以便打印通用方法的表示对象:USER> #'foo #<STANDARD-GENERIC-FUNCTION FOO (0)>
右键单击 演示文稿(
#<...>
内的任意位置)和 selectInspect
,或者将光标放在演示文稿中并按 C-c C-v TAB (slime-inspect-presentation-at-point
).从源文件中,输入
slime-inspect
、a.k.a。 C-c I,输入#'foo
.
在这两种情况下,您都会看到与此类似的视图:
#<STANDARD-GENERIC-FUNCTION {505A9A2B}>
--------------------
Name: FOO
Arguments: (X)
Method class: #<STANDARD-CLASS COMMON-LISP:STANDARD-METHOD>
Method combination: #<SB-PCL::STANDARD-METHOD-COMBINATION STANDARD () {1000214003}>
Methods:
(INTEGER) [remove method]
(STRING) [remove method]
(....)
每个 [remove method]
文本实际上是一个按钮,单击或按 Return 可以从通用函数中删除关联的方法。