[plt-scheme] Overriding private methods with class.ss?

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Sat Aug 18 16:07:28 EDT 2007

At Sat, 18 Aug 2007 15:31:00 -0400, "Henk Boom" wrote:
> Hi, I was reading the class.ss documentation in the help desk, and as
> far as I can tell there is no way to have private overridable methods:

It's not obvious (and I haven't yet gotten to the `class' part in the
new guide), but `define-local-member-name' is what you're looking for.


The `define-local-member-name' form binds an identifier to a fresh
representation of an external name. In the scope of the binding, uses
of the identifier as a method name refer to a method that is not
accessible outside the scope of the binding.

Here's an example (based on your problem):

 (define-values (c% sub-c%)
   (let ()
     ;; `handle-key' has local scope:
     (define-local-member-name handle-key)
    
     (define c%
       (class object%
         (define/public (handle-event e)
           (if (eq? e 'key)
               (handle-key e)
               "something else"))
         (define/public (handle-key e)
           "key")
         (super-new)))
    
     (define sub-c%
       (class c%
         (define/override (handle-key e)
           "overridden key")
         (super-new)))
     
     (values c% sub-c%)))

 ;; As expected:
 (send (new c%) handle-event 'mouse)   ; => "something else"
 (send (new c%) handle-event 'key)     ; => "key"
 (send (new sub-c%) handle-event 'key) ; => "overridden key"

 ;; But you can't see `handle-key' out here:
 (send (new c%) handle-key 'key) ; => no such method for `send'
 (class c% 
   (define/override (handle-key x) #f)
   (super-new))                  ; => no such method to override


The `define-local-member-name' form is probably most useful at the
module level. And at module level, identifiers bound by
`define-local-member-name' can be exported to make methods visible only
in specific modules.

Matthew



Posted on the users mailing list.