🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.lang.clos
Article #414

Re: accessing clos objects

#414
From: kanderso
Date: Tue, 12 Feb 1991 17:52
120 lines
4284 bytes
  It's not clear how one would do this with :BEFORE and/or :AFTER
  methods.  An ordinary method specialized on the class in question
  would never get called, since MAKE-INSTANCE gets called on symbols and
  classes.  So, presumably the idea is to define a method on
  MAKE-INSTANCE that is EQL specialized to the class itself, or the name
  of the class.  But a :BEFORE or :AFTER method isn't going to be able
  to get access to the new instance, only to the class.  One would have
  to use, for instance, an :AROUND or a primary method and use
  CALL-NEXT-METHOD.  Thus:

    (DEFCLASS FLINTSTONE ()
        ((INSTANCES :ALLOCATION :CLASS
                    :INITFORM '()
                    :ACCESSOR FLINTSTONE-INSTANCES)
         (NAME :ACCESSOR FLINTSTONE-NAME)))

    (DEFMETHOD MAKE-INSTANCE ((F-CLASS (EQL (FIND-CLASS 'FLINTSTONE)))
                              &REST INITARGS)
      (LET ((NEW-FLINTSTONE (CALL-NEXT-METHOD)))
        (PUSH NEW-FLINTSTONE (FLINTSTONE-INSTANCES NEW-FLINTSTONE))
        NEW-FLINTSTONE))

  In general, I believe that EQL methods are fairly lousy with respect
  to performance.  Alternatively, on ecould define the recording
  behavior on SHARED-INITIALIZE, or something like that.  Defining a new
  metaclass is probably a better solution, certainly aesthetically
  speaking, although it makes it a little trickier to have the above
  behavior be inherited.

Here's an example of doing it each way.  It once ran in PCL.

;;;-*-Mode:LISP; Package:(PCL LISP 1000); Base:10; Syntax:Common-lisp -*-

(defclass named-mixin
	  ()
     ((name :initarg :name :initform NIL :reader name)))

(defmethod print-object ((thing named-mixin) stream)
  (printing-random-thing (thing stream)
   (format stream "~a ~a" (class-name (class-of thing)) (name thing))))


(defclass compatible-class-mixin
    ()
  ()
  (:documentation
   "A metaclass mixin that provides compatibility with standard-class."))

(defmethod check-super-metaclass-compatibility
	   ((class compatible-class-mixin) (super standard-class))
  t)

(defmethod describe ((thing compatible-class-mixin) &rest args)
  (apply 'describe-instance thing args))


(defclass instances-class-mixin
	  ()
     ((instances :initform () :accessor class-instances))
  (:documentation
    "Lets a class record its instances."))

(defmethod make-instance ((class instances-class-mixin) &rest initargs)
  (declare (ignore initargs))
  (let ((instance (call-next-method)))
    (add-instance class instance)
    instance))

(defmethod add-instance ((class instances-class-mixin) instance)
  (pushnew instance (class-instances class)))

(defmethod remove-instance ((class instances-class-mixin) instance)
  (setf (class-instances class)
	(delete instance (class-instances class) :test #'eq)))


;;; This version uses :class allocated slots, so each instance knows
;;; who its siblings are but the class doesn't know who its instances
;;; are.

(defclass i-mixin
	  ()
     ((instances :initform () :accessor instances :allocation :class)))

(defmethod *initialize-instance :before ((object i-mixin) &rest initargs)
	   (pushnew object (instances object)))

(defclass foo-x
	  (i-mixin)
     ((x)
      (y)))

(defclass foo-y
	  (i-mixin)
     ((z)
      (y)))

#||
;;; Example.
(defclass instance-recording-class
	  (instances-class-mixin
	    compatible-class-mixin
	    standard-class)
     ())

(defclass ifrob ()
     ((x :initarg x :accessor x)
      (y :initarg y :accessor y))
  (:metaclass instance-recording-class))

(defclass jfrob (ifrob)
     ((z :initarg x :accessor z))
  (:metaclass instance-recording-class))

(setq x (make-instance 'ifrob))
(setq y (make-instance 'jfrob))
(class-instances (find-class 'ifrob))

||#
Technical Details
Message-ID: <9102121807.AA16036@cheops.cis.ohio-state.edu>
Path: arc1-ca.pugleaf.net!utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!usc!wuarchive!uunet!tut.cis.ohio-state.edu!BBN.COM!kanderso
References: <9102121706.AA06034@mingus.mitre.org>

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!usc!wuarchive!uunet!tut.cis.ohio-state.edu!BBN.COM!kanderso
From: kanderso@BBN.COM
Newsgroups: comp.lang.clos
Subject: Re: accessing clos objects
Message-ID: <9102121807.AA16036@cheops.cis.ohio-state.edu>
Date: 12 Feb 91 17:52:53 GMT
References: <9102121706.AA06034@mingus.mitre.org>
Sender: welch@tut.cis.ohio-state.edu
Distribution: inet
Organization: CommonLoops
Lines: 120