[plt-scheme] Reflection in class.ss

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Wed Mar 28 20:13:35 EDT 2007

At Wed, 28 Mar 2007 12:49:30 -0400 (EDT), Daniel Yoo wrote:
> If you can use accessor methods to get at those fields, then you can use 
> the following:
> 
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
>    ;; call-accessor: object symbol -> any
>    ;; Calls a 0-arity method whose name is determined at
>    ;; runtime.
>    (define (call-accessor object accessor-name)
>      (define f (make-generic (object-interface object) accessor-name))
>      (send-generic object f))
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

FWIW, I think `make-generic' (as opposed to `generic') is probably a
mistake, and that all reflection should go through an inspector.

At Wed, 28 Mar 2007 09:14:02 -0700 (PDT), Noel Welsh wrote:
> I'm trying to get the value of an object's field given the field's name.  The 
> OO system (class.ss) provides get-field, but the field name is not evaluated, 
> and so must be a literal. 

It's not evaluated as an expression, but it can be bound via
`define-member-name'...

> This is not sufficient use -- I have a list of 
> names and want to lookup the value at runtime.  Can this be done?

It depends on where the names come from. If you have a list

 (define fields
   (list 'one 'two 'three)

then you can change it to

 (define fields
   (list (member-name-key one)
         (member-name-key two)
         (member-name-key three)))

and then use the list in something like

 (map (lambda (id)
        (define-member-name fld id)
        (get-field fld o))
      fields)

That is, the class system supports abstraction over field names without
relying on reflection.

When you need reflection, though, there's always the
inspector-controlled reflection layer that Danny showed.

Matthew



Posted on the users mailing list.