Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

additional properties to slot definition

http://mop.lisp.se/concepts.html says:

An implementation is free to add additional properties to the canonicalized slot specification provided these are not symbols accessible in the common-lisp-user package, or exported by any package defined in the ANSI Common Lisp standard.

with example:

(defclass sst (plane)
     ((mach mag-step 2
            locator sst-mach
            locator mach-location
            :reader mach-speed
            :reader mach))
  (:metaclass faster-class)
  (another-option foo bar))

But when i try:

(defclass a () ((x my-option 123)))

SBCL compile it with error:

Invalid initialization argument: MY-OPTION in call for class

                SB-MOP:STANDARD-DIRECT-SLOT-DEFINITION>.    

[Condition of type SB-PCL::INITARG-ERROR]

So the question. How can I add additional properties (like "my-option") to the slot definition?

like image 899
user1312837 Avatar asked Feb 24 '14 11:02

user1312837


1 Answers

An implementation can do that. But the user can't add random properties. If a Common Lisp implementation supports the Meta-Object Protocol, one can add it via a custom Metaclass. But this means that one also needs to provide ways to compute slots, etc.

That's advanced Lisp. The Book The Art of the Metaobject Protocol has an example in chapter 3, Extending the Language.

A simple example (works in LispWorks):

(defclass foo-meta-class (standard-class) ())

(defclass foo-standard-direct-slot-definition (standard-direct-slot-definition)
  ((foo :initform nil :initarg :foo)))

(defclass foo-standard-effective-slot-definition (standard-effective-slot-definition)
  ((foo :initform nil :initarg :foo)))

(defmethod clos:direct-slot-definition-class ((class foo-meta-class) &rest initargs)
  (find-class 'foo-standard-direct-slot-definition))

(defmethod clos:effective-slot-definition-class ((class foo-meta-class) &rest initargs)
  (find-class 'foo-standard-effective-slot-definition))

Let's use it in an user-defined class:

(defclass foo ()
  ((a :initarg :a :foo :bar))
  (:metaclass foo-meta-class))

The slot-definition object then will have a slot foo with content bar.

CL-USER 10 > (find-class 'foo)
#<FOO-META-CLASS FOO 42200995AB>

CL-USER 11 > (class-direct-slots *)
(#<FOO-STANDARD-DIRECT-SLOT-DEFINITION A 42200B4C7B>)

CL-USER 12 > (describe (first *))

#<FOO-STANDARD-DIRECT-SLOT-DEFINITION A 42200B4C7B> is a FOO-STANDARD-DIRECT-SLOT-DEFINITION
FOO                     :BAR
READERS                 NIL
WRITERS                 NIL
NAME                    A
INITFORM                NIL
INITFUNCTION            NIL
TYPE                    T
FLAGS                   1
INITARGS                (:A)
ALLOCATION              :INSTANCE
DOCUMENTATION-SLOT      NIL

Obviously there is more to it, if the property should have any real meaning.

like image 100
Rainer Joswig Avatar answered Oct 30 '22 00:10

Rainer Joswig