首页 > 解决方案 > 不能在 CLIPS 消息处理程序中引用继承的插槽

问题描述

我有一个抽象类,其中定义了一个名为的只读插槽storage-size

(defclass digital-media (is-a USER)
    (role abstract)

    (slot storage-size
        (type INTEGER)
        (default -1)
        (access read-only)
        (visibility public)))

我已将主消息处理程序附加到引用同一storage-size插槽的抽象类中。

(defmessage-handler digital-media read-storage primary (?offset ?size)
    (if (or (< ?offset 0) (>= ?offset ?self:storage-size))
        then
        (printout t "Read offset " ?offset " is out of bounds, max storage size is " ?self:storage-size crlf)
        (halt))

    (printout t "Still running for some reason..." crlf))

在创建具体类时,继承的字段只有在隐式声明时才能按预期工作:

(defclass compact-disk (is-a digital-media)
    (role concrete))

(make-instance my-disk of compact-disk)
(send [my-disk] print)
; [my-disk] of compact-disk
; (storage-size -1)

(send [my-disk] read-storage 128 1024)
; Read offset 128 is out of bounds, max storage size is -1

但是,当我为其提供默认值时,消息处理程序不起作用:

(defclass compact-disk (is-a digital-media)
    (role concrete)

    (slot storage-size
        (source composite)
        (default 650)))

(make-instance my-disk of compact-disk)
(send [my-disk] print)
; [my-disk] of compact-disk
; (storage-size 650)

(send [my-disk] read-storage 128 1024)
; [MSGPASS3] Static reference to slot storage-size of class digital-media does not apply to [my-disk] of compact-disk
; [ARGACCES5] Function >= expected argument #2 to be of type integer or float
; [PRCCODE4] Execution halted during the actions of message-handler read-storage primary in class digital-media
; FALSE

标签: clips

解决方案


我不完全理解其中的原理,但是当您更改子类的插槽方面时,当子类的实例调用时,超类消息处理程序不能使用该插槽的插槽速记引用。因此,在读取存储处理程序中,您需要将 ?self:storage-size 更改为(发送 ?self get-storage-size)。

我想这会强制封装超类。例如,读取存储消息处理程序知道 ?self:storage-size 引用必须是整数,并且子类不可能将此插槽的类型重新定义为字符串,然后使用包含字符串而不是插槽的整数值的子类实例。


推荐阅读