所以我的想法是减少对对象实例的调用量,因为它显然是范围内唯一的实例。
这是一个代码示例:
(defun read-plist (plist)
(let ((plist-reader (make-instance 'plist-reader))
(loop for (indicator value) in plist
do (read-indicator plist-reader indicator)
do (read-value plist-readere value))
plist-reader))
这就是我想要的样子:
(defun read-plist (plist)
(let ((plist-reader (make-instance 'plist-reader))
(with-methods (read-indicator (rv read-value)
plist-reader)
(loop for (indicator value) in plist
do (read-indicator indicator)
do (rv value)))
plist-reader))
我认为这并不是最好的例子,因为它使代码看起来更加复杂。但我可以想象一种情况,它会大大减少复杂性。也许我正在寻找一个完全错误的方向,但我最初的想法是当范围明显是本地时减少名称的使用。拥有一个自己的小包,用函数取代将方法绑定到特定对象的需要,这是否是一个更好的做法?我想没有一个真正的答案,但无论如何......你对宏观有何看法? :D
我尝试以这种方式定义宏的方向:
(defmacro with-methods (methods class-instance &rest code)
...)
但看来我需要查看所有其余代码,找到给定方法的所有出现并将它们修改为列表。它给我带来了性能问题的困境。也许我错过了一种经典的方法?从 Common Lisp 初学者的角度来看,我发现文档无法搜索,只有在 ChatGPT 对其进行修改之后才可读。
正如@Barmar 在评论中解释的那样,
with-methods
可以扩展为 flet
:
(defmacro with-methods (methods class-instance &rest body)
"Reduces calls to class methods down to their names and rest parameters,
given that the first argument to every method is class instance.
Acts similarly to 'with-slots'.
'methods' argument is a list of method names, that may contain
sublists with short names like so:
(actual-method-name-1 (mn-2 actual-method-name-2)"
`(flet ,(loop for method-name in methods
if (listp method-name)
collect `(,(first method-name) (&rest args)
(apply #',(second method-name) ,class-instance args))
else
collect `(,method-name (&rest args)
(apply #',method-name ,class-instance args)))
,@body))
其中
loop
部分负责按以下方式传递给宏的方法名称:
(method-name-1 (m-name-2 method-name-2))
我测试了代码,它的效果非常好。请原谅多次取消引用,我希望它是可读的:D