3 ;;;; Copyright (C) 1998, 1999 Free Software Foundation, Inc.
5 ;;;; This program is free software; you can redistribute it and/or modify
6 ;;;; it under the terms of the GNU General Public License as published by
7 ;;;; the Free Software Foundation; either version 2, or (at your option)
8 ;;;; any later version.
10 ;;;; This program is distributed in the hope that it will be useful,
11 ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 ;;;; GNU General Public License for more details.
15 ;;;; You should have received a copy of the GNU General Public License
16 ;;;; along with this software; see the file COPYING. If not, write to
17 ;;;; the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18 ;;;; Boston, MA 02111-1307 USA
22 ;;;; This software is a derivative work of other copyrighted softwares; the
23 ;;;; copyright notices of these softwares are placed in the file COPYRIGHTS
25 ;;;; This file is based upon describe.stklos from the STk distribution by
26 ;;;; Erick Gallesio <eg@unice.fr>.
29 (define-module (oop goops describe)
30 :use-module (oop goops)
31 :use-module (ice-9 session)
32 :use-module (ice-9 format))
34 (export describe) ; Export the describe generic function
37 ;;; describe for simple objects
39 (define-method describe ((x <top>))
40 (format #t "~s is " x)
42 ((integer? x) (format #t "an integer"))
43 ((real? x) (format #t "a real"))
44 ((complex? x) (format #t "a complex number"))
45 ((null? x) (format #t "an empty list"))
46 ((boolean? x) (format #t "a boolean value (~s)" (if x 'true 'false)))
47 ((char? x) (format #t "a character, ascii value is ~s"
49 ((symbol? x) (format #t "a symbol"))
50 ((list? x) (format #t "a list"))
51 ((pair? x) (if (pair? (cdr x))
52 (format #t "an improper list")
53 (format #t "a pair")))
54 ((string? x) (if (eqv? x "")
55 (format #t "an empty string")
56 (format #t "a string of length ~s" (string-length x))))
57 ((vector? x) (if (eqv? x '#())
58 (format #t "an empty vector")
59 (format #t "a vector of length ~s" (vector-length x))))
60 ((eof-object? x) (format #t "the end-of-file object"))
61 (else (format #t "an unknown object (~s)" x)))
65 (define-method describe ((x <procedure>))
66 (let ((name (procedure-name x)))
68 (format #t "`~s'" name)
71 (display (if name #\a "an anonymous"))
72 (display (cond ((closure? x) " procedure")
73 ((not (struct? x)) " primitive procedure")
74 ((entity? x) " entity")
80 ;;; describe for GOOPS instances
82 (define (safe-class-name class)
83 (if (slot-bound? class 'name)
87 (define-method describe ((x <object>))
88 (format #t "~S is an instance of class ~A~%"
89 x (safe-class-name (class-of x)))
91 ;; print all the instance slots
92 (format #t "Slots are: ~%")
93 (for-each (lambda (slot)
94 (let ((name (slot-definition-name slot)))
95 (format #t " ~S = ~A~%"
97 (if (slot-bound? x name)
98 (format #f "~S" (slot-ref x name))
100 (class-slots (class-of x)))
104 ;;; Describe for classes
106 (define-method describe ((x <class>))
107 (format #t "~S is a class. It's an instance of ~A~%"
108 (safe-class-name x) (safe-class-name (class-of x)))
111 (format #t "Superclasses are:~%")
112 (for-each (lambda (class) (format #t " ~A~%" (safe-class-name class)))
113 (class-direct-supers x))
116 (let ((slots (class-direct-slots x)))
118 (format #t "(No direct slot)~%")
120 (format #t "Directs slots are:~%")
121 (for-each (lambda (s)
122 (format #t " ~A~%" (slot-definition-name s)))
127 (let ((classes (class-direct-subclasses x)))
129 (format #t "(No direct subclass)~%")
131 (format #t "Directs subclasses are:~%")
132 (for-each (lambda (s)
133 (format #t " ~A~%" (safe-class-name s)))
137 (format #t "Class Precedence List is:~%")
138 (for-each (lambda (s) (format #t " ~A~%" (safe-class-name s)))
139 (class-precedence-list x))
142 (let ((methods (class-direct-methods x)))
144 (format #t "(No direct method)~%")
146 (format #t "Class direct methods are:~%")
147 (for-each describe methods))))
149 ; (format #t "~%Field Initializers ~% ")
150 ; (write (slot-ref x 'initializers)) (newline)
152 ; (format #t "~%Getters and Setters~% ")
153 ; (write (slot-ref x 'getters-n-setters)) (newline)
157 ;;; Describe for generic functions
159 (define-method describe ((x <generic>))
160 (let ((name (generic-function-name x))
161 (methods (generic-function-methods x)))
163 (format #t "~S is a generic function. It's an instance of ~A.~%"
164 name (safe-class-name (class-of x)))
167 (format #t "(No method defined for ~S)~%" name)
169 (format #t "Methods defined for ~S~%" name)
170 (for-each (lambda (x) (describe x #t)) methods)))))
173 ;;; Describe for methods
175 (define-method describe ((x <method>) . omit-generic)
176 (letrec ((print-args (lambda (args)
177 ;; take care of dotted arg lists
178 (cond ((null? args) (newline))
181 (display (safe-class-name (car args)))
182 (print-args (cdr args)))
185 (display (safe-class-name args))
189 (format #t " Method ~A~%" x)
191 ;; Associated generic
192 (if (null? omit-generic)
193 (let ((gf (method-generic-function x)))
195 (format #t "\t Generic: ~A~%" (generic-function-name gf))
196 (format #t "\t(No generic)~%"))))
199 (format #t "\tSpecializers:")
200 (print-args (method-specializers x))))