All Manuals > LispWorks IDE User Guide > 17 The Inspector

17.8 Creating new inspection formats

There is a default inspection format for each Lisp object.

The Inspector tool can be customized by adding new inspection formats. To do this, you need to define new methods on the generic function get-inspector-values.

get-inspector-values takes two arguments: object and mode, and returns 5 values: names, values, getter, setter and type.

object
The object to be inspected.
mode
This argument should be either nil or eql to some other symbol. The default format for inspecting any object is its nil format. The nil format is defined for all Lisp objects, but it might not be sufficiently informative for your classes and it may be overridden.
names
The slot-names of object.
values
The values of the slots corresponding to names. The Inspector displays the names and values in two columns in the scrollable pane.
getter
This is currently ignored. Use nil.
setter
This is a function that takes four arguments: an object (of the same class as object), a slot-name, an index (the position of the slot-name in names, counting from 0), and finally a new-value. (It is usual to ignore either the slot-name or the index.) This function should be able to change the value of the appropriate slot of the given object to the new-value.
type
This is the message to be displayed in the message area of the Inspector. This is typically either mode or - if mode is nil - then the name of the class of object.

17.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 Follow 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.


LispWorks IDE User Guide (Unix version) - 01 Dec 2021 19:37:15