Paste number 65702: Adding mixins to an instance

Index of paste annotations: 2 | 1

Paste number 65702: Adding mixins to an instance
Pasted by: bobbysmith007
When:1 year, 5 months ago
Share:Tweet this! | http://paste.lisp.org/+1EP2
Channel:#lisp
Paste contents:
Raw Source | XML | Display As
(defclass meta-mixin ()
  ()
  (:documentation "A class that lets you pass in mixins to add to an instance, as initargs.
    It will handle figuring out a reasonable class name, ensuring that it exists, and
    changing the class on instance along the way"))


(defmethod initialize-instance :after ((obj meta-mixin) &rest args &key mixins &allow-other-keys)
  (loop for mixin in (ensure-list mixins)
     do
     (unless (typep obj mixin) 
       (let* ((class-name (class-name (class-of obj)))
	      (class (closer-mop:ensure-class
		      (intern-concat (list class-name "-" mixin))
		      :metaclass (class-of (class-of obj))
		      :direct-superclasses (list (find-class class-name) 
						 (find-class mixin)))))
	 (apply #'change-class obj (class-name class) args)
	 ))))

;; root of our web component library
(defcomponent ucwb::adw-component (html-element meta-mixin)
  ((ucwb::attributes :accessor ucwb::attributes :initarg :attributes :initform ())
   (ucwb::css-classes :initform '() :initarg :css-classes)
   (ucwb::dom-unique-id :initform nil))
  (:default-initargs :dom-id nil))

;; a mixin to allow us to identify search forms
(defclass search-composite-mixin ()
  ())

;; a mixin to allow us to identify elements that represent a bit of where clause on
;; a search form
(defclass search-component-mixin ()
  ((search-clause :accessor search-clause :initarg :search-clause :initform nil)))

;; a mixin to allow us to tag objects as representing a database column
(defclass database-column ()
  ((table :accessor table :initarg :table :initform nil)
   (column :accessor column :initarg :column :initform nil)))


;; A dummy component that shows adding random bits of data to search form components based on its mixin list
(defcomponent search-test (adw-detail-component search-composite-mixin)
  ((name :accessor name
	 ;; labelbox is our standard textbox that has an editability flag
	 ;; determining how it renders
	 :component (xhtml-labelbox :search-clause "name like '%{value}%'"
				    :table "clients" :column "name"
				    :mixins 'search-component-mixin 'database-column))
   (address :accessor address
	    :component (xhtml-labelbox :search-clause "address+city+state like '%{value}%'"
				       :mixins 'search-component-mixin))
   (ordernumber :accessor ordernumber
		:component (xhtml-labelbox :search-clause "ordernumber like '%{value}%' or CAST (billing_id as VARCHAR (16)) like '%{value}%'"
					   :mixins 'search-component-mixin))
   ))

Annotations for this paste:

Annotation number 2: Abstracted adding a mixin to an instance as a method call
Pasted by: bobbysmith007
When:1 year, 5 months ago
Share:Tweet this! | http://paste.lisp.org/+1EP2/2
Paste contents:
Raw Source | Display As
(defmethod add-mixin-to-instance ((obj t) (mixin symbol) &rest initargs)
  "Adds a mixin to the passed in obj, using initargs for reinitialization

   mixin should be a class-name, it should probably define a (shared-initialize :after)
         if it wants to interact with the object (other than as slots)
  "
  (unless (typep obj mixin) 
    (let* ((class-name (class-name (class-of obj)))
	   (class (closer-mop:ensure-class
		   (intern-concat (list class-name "-" mixin))
		   :metaclass (class-of (class-of obj))
		   :direct-superclasses (list (find-class class-name) 
					      (find-class mixin)))))
      (apply #'change-class obj (class-name class) initargs))))

Annotation number 1: correction
Pasted by: bobbysmith007
When:1 year, 5 months ago
Share:Tweet this! | http://paste.lisp.org/+1EP2/1
Paste contents:
Raw Source | Display As
;;The name slot should actually be defined as follows
(name :accessor name
         ;; labelbox is our standard textbox that has an editability flag
         ;; determining how it renders
         :component (xhtml-labelbox :search-clause "name like '%{value}%'"
                                    :table "clients" :column "name"
                                    :mixins '(search-component-mixin database-column)))

Colorize as:
Show Line Numbers
Index of paste annotations: 2 | 1

Lisppaste pastes can be made by anyone at any time. Imagine a fearsomely comprehensive disclaimer of liability. Now fear, comprehensively.