[plt-scheme] Reflection in class.ss

From: Dave Gurnell (d.j.gurnell at gmail.com)
Date: Thu Mar 29 12:35:17 EDT 2007

Daniel,

Many thanks for your post on this - it looks really useful for  
something I'm working on. I had a play with the get-field-at-runtime  
approach you mentioned. It seems to work fine until inheritance is  
bought into play. See my adaptation of your example below for more  
information ... the last line raises an exception:

     "object:c2%-ref: slot index for <struct:object:c2%> not in [0,  
0]: 1"

I presume this has something to do with inspectors, but I can't see  
how one would get around it as the procedure field-accessor-proc  
takes an object as an argument and not a class. Any ideas?

Thanks again,

-- Dave

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(module get-field-at-runtime mzscheme
   (require (lib "class.ss")
            (only (lib "1.ss" "srfi") list-index))


   ;; get-runtime-field: object symbol -> any
   ;; Tries to get the field value from the object.
   ;; We must be able to inspect the class, or else this fails.
   (define (get-runtime-field obj name)
     (let*-values ([(class skipped) (object-info obj)]
                   [(name-symbol
                     field-k
                     field-name-list
                     field-accessor-proc
                     field-mutator-proc
                     super-class
                     skipped)
                    (class-info class)])
       (field-accessor-proc obj
                            (list-index (lambda (x)
                                          (eq? x name))
                                        field-name-list))))
   ;; example usage:
   (define c1%
     (class object%
       (init-field family-name)
       (inspect #f)
       (super-new)))

   (define c2%
     (class c1%
       (init-field first-name)
       (inspect #f)
       (super-new)))

   (define obj1 (new c1% [family-name "Gurnell"]))
   (define obj2 (new c2% [family-name "Gurnell"] [first-name "Dave"]))

   (display (get-runtime-field obj1 'family-name)) (newline)
   (display (get-runtime-field obj2 'first-name))  (newline)
   (display (get-runtime-field obj2 'family-name)) (newline))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


Posted on the users mailing list.