是否可以在现有类中动态添加一个超类
在 Common-Lisp CLOS 中,
是否可以动态添加一个超类 在现有的班级中。
更新:
我想定义 defassoc 类型的宏来关联某些行为 使用相同参数的方法/函数,
例如
(defassoc (gname (s (g group)))
((name1 (name ((corresponding-task task g) s)))
(record1 (record ((corresponding-task task g) s))))
(let ((n name1)
(r record1))
(if (and name1 record1)
(display name1 record1)
(call-next-method))))
展开到
(symbol-macrolet ((name1 (name ((corresponding-task task g) s)))
(record1 (record ((corresponding-task task g) s))))
(defmethod gname :after (s (g group))
(let ((n name1) (r record1))
(if (and name1 record1)
(display name1 record1)
(call-next-method)))))
这里,它确保每当 (gname (s (g group)) 被调用时 这里应该调用相应的任务来组
(name ((corresponding-task task g) s)
(record ((corresponding-task task g) s)
我使用了这个宏
(defmacro defassoc ((main-method main-method-lambda-list)
funspec-list &body body)
`(symbol-macrolet ,(mapcar (lambda (fspec)
(destructuring-bind (name f) fspec
(list name f)))
funspec-list)
(defmethod
,main-method ,mod ,main-method-lambda-list
,@(if body
body
`(if (and
,@(mapcar (lambda (e)
(car e))
funspec-list))
(call-next-method)))))
但问题是它会覆盖
(defmethod gname :after (s (g group))
...)
(如果有的话,我可以验证它是否有一个,)
但我希望它适用于任何对象是否有要覆盖的方法
因此基本上应该需要更改该类和方法中的任何内容的代码。
所以我决定动态添加父类来定义这个方法。
其他方式可能是 defadvide 或 fwrapper 但它不存在于 SBCL 中。
In Common-Lisp CLOS
Is it possible to dynamically add one more super class
in existing class.
Update:
I wanted to defined defassoc kind of macro that will associated some behaviour
with method/function using same argument
e.g.
(defassoc (gname (s (g group)))
((name1 (name ((corresponding-task task g) s)))
(record1 (record ((corresponding-task task g) s))))
(let ((n name1)
(r record1))
(if (and name1 record1)
(display name1 record1)
(call-next-method))))
expand to
(symbol-macrolet ((name1 (name ((corresponding-task task g) s)))
(record1 (record ((corresponding-task task g) s))))
(defmethod gname :after (s (g group))
(let ((n name1) (r record1))
(if (and name1 record1)
(display name1 record1)
(call-next-method)))))
Here it is ensuring when ever (gname (s (g group)) is call
here should be call for corresponding task to group
(name ((corresponding-task task g) s)
(record ((corresponding-task task g) s)
I used this macro
(defmacro defassoc ((main-method main-method-lambda-list)
funspec-list &body body)
`(symbol-macrolet ,(mapcar (lambda (fspec)
(destructuring-bind (name f) fspec
(list name f)))
funspec-list)
(defmethod
,main-method ,mod ,main-method-lambda-list
,@(if body
body
`(if (and
,@(mapcar (lambda (e)
(car e))
funspec-list))
(call-next-method)))))
But problem is that it will overwrite the
(defmethod gname :after (s (g group))
...)
(If it has any, I can verify it if it has one or not,)
But I want it to work for any object whether it has that method to overwrite or not
So basically it should be needed to change in code for any thing in that classes and methods.
So one way I decided that to dynamically add parent class to define this method on it.
Other way could be defadvide or fwrapper but it is not present in SBCL.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
是的,这是可能的。最简单的方法就是重新定义类。您可以通过再次调用
DEFCLASS
来实现这一点。如果你想做更复杂的事情,你必须求助于 MOP(元对象协议)。基本上,您想要做的所有事情都可以使用 MOP 实现,但我需要更详细的信息来了解您想要做什么,以便进一步解释。Yes, it's possible. The easiest way would be to simply redefine the class. You do that by issuing another call to
DEFCLASS
. If you want to do more complicated things, you have to resort to the MOP (MetaObject Protocol). Essentially everything you'd ever want to do is possible using the MOP, but I would need more detailed information as to what it is you're trying to do in order to explain it further.