问题
I need to retrieve a slot value (passing a slot name) from an instance which may contain other instances. Example:
(defclass MAINCONTROLLER (is-a USER)
(slot uuid
(type STRING))
(slot param
(type INSTANCE))
(multislot zones
(type INSTANCE))
(slot state
(allowed-values a b c))
(slot pump
(allowed-values on off)))
(make-instance mainController of MAINCONTROLLER
(uuid "myController123")
(param [param-mainController])
(zones [zone1] [zone2])
(state a)
(pump on))
Slot named "param" contains an instance called [param-mainController].
CLIPS documentation suggests to retrieve a slot value with a send command with put- parameter. I tried to use a generic function to retrieve a parameter only by passing the slotname.
(defmessage-handler USER get-param (?param-name)
(printout t "Slot value: " ?self:?param-name crlf))
But executing it I get:
(send [mainController] get-param state)
[MSGPASS2] No such instance mainController in function send.
FALSE
Some questions:
1) Do I need always to define a (create-accessor read) for every slot I need to read withsend command?
2) Could you please suggest some examples with best practices to retrieve a slot value from an instance?
Thank you, Nic
回答1:
By default, get- and put- handlers are created for slots. To retrieve specific slots use (send <instance> get-<symbol>) outside of a class's message-handlers and ?self:<symbol> within. To retrieve a slot where the slot name is stored in a variable, use (send <instance> (sym-cat get- <variable>)). Using ?self:<variable> is invalid syntax for slot shorthand references.
CLIPS> (clear)
CLIPS>
(defclass MAINCONTROLLER (is-a USER)
(slot uuid
(type STRING))
(slot param
(type INSTANCE))
(multislot zones
(type INSTANCE))
(slot state
(allowed-values a b c))
(slot pump
(allowed-values on off)))
CLIPS>
(defmessage-handler MAINCONTROLLER myprint ()
(printout t ?self:state crlf))
CLIPS>
(deffunction retrieve-slot (?ins ?slot-name)
(printout t (send ?ins (sym-cat get- ?slot-name)) crlf))
CLIPS>
(make-instance mainController of MAINCONTROLLER
(uuid "myController123")
(param [param-mainController])
(zones [zone1] [zone2])
(state a)
(pump on))
[mainController]
CLIPS> (send [mainController] get-state)
a
CLIPS> (send [mainController] myprint)
a
CLIPS> (retrieve-slot [mainController] state)
a
CLIPS>
来源:https://stackoverflow.com/questions/39879426/get-slot-value-of-an-object