是否可以在现有类中动态添加一个超类

发布于 2024-11-29 22:40:42 字数 1939 浏览 3 评论 0原文

在 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))
      ...)

(如果有的话,我可以验证它是否有一个,)

但我希望它适用于任何对象是否有要覆盖的方法

因此基本上应该需要更改该类和方法中的任何内容的代码。

所以我决定动态添加父类来定义这个方法。

其他方式可能是 defadvidefwrapper 但它不存在于 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

纸短情长 2024-12-06 22:40:42

是的,这是可能的。最简单的方法就是重新定义类。您可以通过再次调用 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文