NextPrevUpTopContentsIndex

16.8.1 Example

Consider the following implementation of doubly-linked lists.

(in-package "DLL")
(defstruct (dll (:constructor construct-dll)
                (:print-function print-dll))
  previous-cell
  value
  next-cell)
(defun make-dll (&rest list)
  (loop with first-cell 
        for element in list
        for previous = nil then cell
        for cell = (construct-dll :previous-cell cell
                                  :value element)
        doing
        (if previous
            (setf (dll-next-cell previous) cell)
          (setq first-cell cell))
        finally
        (return first-cell)))
(defun print-dll (dll stream depth)
  (declare (ignore depth))
  (format stream "#<dll-cell ~A>" (dll-value dll)))

You can inspect a single cell by inspecting the following object:

(dll::make-dll "mary" "had" "a" "little" "lamb")

The resulting Inspector shows three slots: dll::previous-cell with value nil , value with value "mary" and dll::next-cell with value #<dll-cell had> .

In practice, you are more likely to want to inspect the whole doubly-linked list in one window. To do this, define the following method on get-inspector-values .

(in-package "DLL")
(defun dll-root (object)
  (loop for try = object then next
        for next = (dll-previous-cell try)
        while next
        finally
        (return try)))
(defun dll-cell (object number)
  (loop for count to number
        for cell = object then (dll-next-cell cell)
        finally
        (return cell)))
(defmethod lw:get-inspector-values ((object dll) 
  (mode (eql 'follow-links)))
  (let ((root (dll-root object)))
     (values
       (loop for cell = root then (dll-next-cell cell)
             for count from 0
             while cell
             collecting count)
       (loop for cell = root then (dll-next-cell cell)
     while cell
             collecting (dll-value cell))
       nil
       #'(lambda (object key index new-value)
     (declare (ignore key))
     (setf (dll-value (dll-cell (dll-root object) index)) new-value))
       "FOLLOW-LINKS")))

Inspecting the same object with the new method defined displays a new tab in the Inspector "Follow Links". This shows five slots, numbered from 0 to 4 with values "mary" "had" "a" "little" and "lamb" .

The following example adds another method to get-inspector-values which inspects cells rather than their value slots. The cells are displayed in a "Fllow Cells" tab of Inspector. The setter updates the next-cell . Use this new mode to inspect the "lamb" cell - that is, double-clink on the "lamb" cell in the "Follow Cells" tab - and then set its next-cell slot to (make-dll "with" "mint" "sauce") .

(in-package "DLL")
(defmethod lw:get-inspector-values
 ((object dll) (mode (eql 'follow-cells)))
  (let ((root (dll-root object)))
     (values
       (loop for cell = root then (dll-next-cell cell)
             for count from 0
             while cell
             collecting count)
       (loop for cell = root then (dll-next-cell cell)
     while cell
             collecting cell)
       nil
       #'(lambda (object key index new-value)
     (declare (ignore key))
     (setf (dll-next-cell (dll-cell (dll-root object) index)) new-value))
       "FOLLOW-CELLS")))

The extended sentence can now be inspected in the follow-links mode.

 


Common LispWorks User Guide (Macintosh version) - 21 Feb 2008

NextPrevUpTopContentsIndex