Common lisp defmethod和defun的Common Lisp特殊变量范围不同?
要么我遗漏了一些非常愚蠢的东西,要么defmethod和defun的特殊变量范围出人意料地不同(使用SBCL 1.1.14进行测试):Common lisp defmethod和defun的Common Lisp特殊变量范围不同?,common-lisp,scope,Common Lisp,Scope,要么我遗漏了一些非常愚蠢的东西,要么defmethod和defun的特殊变量范围出人意料地不同(使用SBCL 1.1.14进行测试): 正如所料: (defun ttprint-object (prefix out) (format out "~A: in defun: < ~A >~%" prefix *print-readably*)) (let ((*print-readably* t)) (format t "let: calling defun: < ~A &
(defun ttprint-object (prefix out)
(format out "~A: in defun: < ~A >~%" prefix *print-readably*))
(let ((*print-readably* t))
(format t "let: calling defun: < ~A >~%" *print-readably*)
(ttprint-object "from let" t))
let: calling defun: < T >
from let: in defun: < T >
CL-USER> (let ((*print-readably* t))
(ttprint-object "from let" t)
(format t "let: calling defmethod: < ~A >~%" *print-readably*)
(format t "let: ~w" (make-instance 'empty)))
from let: in defun: < T >
let: calling defmethod: < T >
let: in defmethod: < T >
from defmethod: in defun: < T >
(定义ttprint对象(前缀输出)
(格式化为“~A:in-defun:<~A>~%”前缀*打印可读*)
(let((*可阅读打印*t))
(格式t“let:calling defun:<~A>~%”*打印可读*)
(ttprint对象“来自let”t))
let:调用defun:
从let:in defun:
(defun ttprint-object (prefix out)
(format out "~A: in defun: < ~A >~%" prefix *print-readably*))
(let ((*print-readably* t))
(format t "let: calling defun: < ~A >~%" *print-readably*)
(ttprint-object "from let" t))
let: calling defun: < T >
from let: in defun: < T >
(defclass empty () ())
(defmethod print-object ((self empty) out)
(format out "in defmethod: < ~A >~%" *print-readably*)
(ttprint-object "from defmethod" out))
(let ((*print-readably* t))
(ttprint-object "from let" t)
(format t "let: calling defmethod: < ~A >~%" *print-readably*)
(format t "let: ~A" (make-instance 'empty)))
from let: in defun: < T >
let: calling defmethod: < T >
let: in defmethod: < NIL >
from defmethod: in defun: < NIL >
CL-USER> (let ((*print-readably* t))
(ttprint-object "from let" t)
(format t "let: calling defmethod: < ~A >~%" *print-readably*)
(format t "let: ~w" (make-instance 'empty)))
from let: in defun: < T >
let: calling defmethod: < T >
let: in defmethod: < T >
from defmethod: in defun: < T >
(defclass empty())
(defmethod打印对象((自空)输出)
(格式化为“in-defmethod:<~A>~%”*以可读方式打印*)
(ttprint对象“从defmethod”输出)
(let((*可阅读打印*t))
(ttprint对象“from let”t)
(格式t“let:调用defmethod:<~A>~%”*以可读方式打印*)
(格式t“let:~A”(使实例为空)
从let:in defun:
let:调用defmethod:
let:在def方法中:
来自defun中的defmethod:
(progn
(setq *print-readably* t)
(ttprint-object "from setf" t)
(format t "setf: calling defmethod: < ~A >~%" *print-readably*)
(format t "setf: ~A" (make-instance 'empty)))
from setf: in defun: < T >
setf: calling defmethod: < T >
setf: in defmethod: < NIL >
from defmethod: in defun: < NIL >
(progn)
(setq*打印可读性*t)
(ttprint object“from setf”t)
(格式t“setf:calling defmethod:<~A>~%”*以可读方式打印*)
(格式t“setf:~A”(使实例为空)
从setf:在defun:
setf:调用defmethod:
setf:在defmethod中:
来自defun中的defmethod:
提前感谢,Frank
~A
将*可读打印*绑定为false(添加强调):
arg(任何对象)打印时不带转义字符(如princ)。如果arg是字符串,则其字符将逐字输出。如果arg为nil,则打印为nil;冒号修饰符(~:A)将导致将参数nil打印为(),但如果参数是复合结构,例如列表或向量,则包含的任何nil事件仍将打印为nil
~A
将*打印转义*
绑定为false,将*可读打印*
绑定为false。
当你这样做的时候
(format t "let: ~A" (make-instance 'empty))
~A
指令将*print readable*
绑定为false(即nil
),最后Lisp编写器调用对象的print object
方法。如果不需要此绑定,可以尝试不修改打印机变量的~W
:
参数(任何对象)按照每个打印机控件打印
变量(如通过写入)。此外,~W与深度正确交互
缩写,不将深度计数器重置为零~W不是
接受参数。如果给定冒号修饰符,~W绑定
*将pretty*
打印为true。如果给定at符号修饰符,~W将*打印级别*
和*打印长度*
绑定为零
~W为检测圆度和圆度提供自动支持
分享。如果*打印圆*
的值不是零并且应用了~W
对于循环(或共享)引用的参数
在输出中插入适当的#n#标记,而不是打印
争论
如果使用~W
,则会得到您最初期望的结果:
(defun ttprint-object (prefix out)
(format out "~A: in defun: < ~A >~%" prefix *print-readably*))
(let ((*print-readably* t))
(format t "let: calling defun: < ~A >~%" *print-readably*)
(ttprint-object "from let" t))
let: calling defun: < T >
from let: in defun: < T >
CL-USER> (let ((*print-readably* t))
(ttprint-object "from let" t)
(format t "let: calling defmethod: < ~A >~%" *print-readably*)
(format t "let: ~w" (make-instance 'empty)))
from let: in defun: < T >
let: calling defmethod: < T >
let: in defmethod: < T >
from defmethod: in defun: < T >
CL-USER>(let((*可读打印*t))
(ttprint对象“from let”t)
(格式t“let:调用defmethod:<~A>~%”*以可读方式打印*)
(格式t“let:~w”(使实例为空)
从let:in defun:
let:调用defmethod:
let:in defmethod:
来自defun中的defmethod:
D'oh-谈论“最小惊喜”,特别是因为defmethod和defun的结果不同。非常感谢您快速详尽的回答,非常欢迎!不过,这并不是defmethod
和defun
之间的区别;这是因为~a
将*print readable*
绑定为false,对于对象,~a
调用相应的print object
方法。唯一令人惊讶的是format
绑定了一个值并导致调用另一个方法,在这种情况下,该方法依赖于format
绑定的值。