【问题标题】:CommonLisp Function for dynamically looking up bindings in packages用于动态查找包中绑定的 Common Lisp 函数
【发布时间】:2019-07-04 08:50:41
【问题描述】:

有没有办法动态地请求另一个包中的绑定,动态我的意思是不知道某个包中绑定的确切名称。一个具体的案例是:

在包 B 中,我知道存在一个包 A,它有一个特定的类,我通过(在 LispWorks 中)提取该类的所有直接槽:

(setq direct-slots (mapcar #'slot-definition-name
                           (class-direct-slots (class-of class-in-package-A))))

现在我想使用 MAPCAR 将这些插槽绑定到一些值:

(mapcar #'(lambda (slot) (list slot
                               (funcall slot class-in-package-A)))
             direct-slots)

这不起作用,因为我在包 B 中并且需要包精度才能调用 (funcall slot class-in-package-A)packageA::slot 显然是错误的。有没有一个函数可以在包中搜索某个符号?

【问题讨论】:

  • CLASS-OF ?那么你是在要求元类。
  • 槽名一般不是函数名,因此调用它是没有意义的。你真的想在一个类对象上调用一个槽名吗?那是你要的吗?类对象是一个元类。
  • 也许您应该发布代码,可以使用实际的错误消息进行复制。目前尚不清楚您可能想要做什么与包有关。

标签: package common-lisp clos


【解决方案1】:

如果你有一个 slot-name 并且想在某个对象中获取命名 slot 的值,请使用 slot-value:

(mapcar (lambda (slot-name)
          (slot-value some-object slot-name))
        slot-names)

插槽名称是符号,如果您碰巧“位于”不同的包中,它们不会神奇地丢失它们的包。我认为您的困惑在于您正在考虑访问器,但它们是另一回事(它们在内部使用 slot-value 之类的东西)。

CL-USER> (defpackage #:foo
           (:use #:cl))
#<PACKAGE "FOO">
CL-USER> (defpackage #:bar
           (:use #:cl #:sb-mop))  ; in SBCL
#<PACKAGE "BAR">
CL-USER> (in-package #:foo)
#<PACKAGE "FOO">
FOO> (defclass afoo ()
       ((a :initarg :a)
        (b :initarg :b)))
#<STANDARD-CLASS FOO::AFOO>
FOO> (in-package #:bar)
#<PACKAGE "BAR">
BAR> (mapcar #'slot-definition-name
             (class-direct-slots (find-class 'foo::afoo)))
(FOO::A FOO::B)
BAR> (let ((slot-names (mapcar #'slot-definition-name
                               (class-direct-slots (find-class 'foo::afoo))))
           (obj (make-instance 'foo::afoo
                               :a 1
                               :b 2)))
       (mapcar (lambda (slot-name)
                 (slot-value obj slot-name))
               slot-names))
(1 2)

一般来说,您应该在“用户”代码中使用访问器,并且您应该知道给定对象存在哪些访问器。对于用户代码来说,某个东西是否是 direct 槽也无关紧要。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-03
    • 1970-01-01
    • 2022-10-07
    • 2011-04-27
    • 1970-01-01
    • 1970-01-01
    • 2011-12-24
    相关资源
    最近更新 更多