[plt-scheme] Reflection in class.ss
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