Work at SourceForge, help us to make it a better place! We have an immediate need for a Support Technician in our San Francisco or Denver office.

Close

#629 print-unreadable-object recursion

lisp error
closed-invalid
Bruno Haible
clisp (525)
5
2012-02-14
2012-02-14
Vladimir Tzankov
No

Following code causes infinite recursion:

(defclass c1 ()
((name :initarg :name :accessor name-of)))

(defmethod print-object ((c c1) stream)
(print-unreadable-object (c stream :type t :identity t)
(princ (name-of c) stream)))

(make-instance 'c1)

The message:
*** - SLOT-VALUE: The slot NAME of XXXXXX has no value
where XXXXXX is the newly created instance is to blame

Discussion

  • This is not a bug. If you don't bind a slot, it's normal to get an error when you try to access it.
    Either don't try to read unbound slot, or bind all your slots (with :initform).

    [pjb@kuiper :0 ~]$ clisp -ansi -norc -q
    [1]> (defclass c1 ()
    ((name :initarg :name :accessor name-of)))
    #<STANDARD-CLASS C1>
    [2]> (defmethod print-object ((c c1) stream)
    (print-unreadable-object (c stream :type t :identity t)
    (princ (name-of c) stream)))
    #<STANDARD-METHOD (#<STANDARD-CLASS C1> #<BUILT-IN-CLASS T>)>
    [3]> (make-instance 'c1 :name "Hello")
    #<C1 Hello #x000333D0E7A0>
    [4]> (defmethod print-object ((c c1) stream)
    (print-unreadable-object (c stream :type t :identity t)
    (when (slot-boundp c 'name) (princ (name-of c) stream))))
    WARNING: Replacing method
    #<STANDARD-METHOD (#<STANDARD-CLASS C1> #<BUILT-IN-CLASS T>)> in
    #<STANDARD-GENERIC-FUNCTION PRINT-OBJECT>
    #<STANDARD-METHOD (#<STANDARD-CLASS C1> #<BUILT-IN-CLASS T>)>
    [5]> (make-instance 'c1)
    #<C1 #x000333D29580>
    [6]> (quit)
    [pjb@kuiper :0 ~]$

     
  • Bruno Haible
    Bruno Haible
    2012-02-14

    This is not a bug. When writing a PRINT-OBJECT method you have to be more careful
    and more defensive than elsewhere, precisely because PRINT-OBJECT can be used in
    error messages.

    Change your method like this:
    (defmethod print-object ((c c1) stream)
    (print-unreadable-object (c stream :type t :identity t)
    (when (slot-boundp c 'name) (princ (name-of c) stream))))

     
  • Bruno Haible
    Bruno Haible
    2012-02-14

    • milestone: --> lisp error
    • status: open --> closed-invalid