[plt-scheme] Catch an unknown method error

From: Filipe Cabecinhas (filcab at gmail.com)
Date: Thu Feb 21 04:55:46 EST 2008

On 20 Feb, 2008, at 22:48, Matthias Felleisen wrote:

> I recommend a macro for method calls:
> (send <exp> <name> <exp1> ...)
> -->
> (with-handlers ((... (lambda (x) (printf "method not found ...") ...))
>   (send:proper <exp> <name> <exp1> ...))
> Then re-export new-send as send and write code as usual. -- Matthias

So, I got something like this. At least in minor testing, it seems to  
work. It's a bit ugly here and there (and throws an error for send/ 
apply instead of send).

What I found out is that there are too few exceptions, which is one  
thing Java got (partly?) right. The exn:fail:object exception doesn't  
tell me exactly what went wrong so I had to go around and use a  
regexp. Also I didn't do a macro for send/apply (and others) yet  
because I haven't felt the need (if I do, it won't be much different  
from this one).


(module test scheme/base
   (require (except-in scheme/class send))
   (provide send)

   (define-syntax send
     (syntax-rules ()
       [(_ exp name exp1 ...)
        (let ([obj exp]
              [args (list exp1 ...)])
          (with-handlers (((lambda (e)
                             (and (exn:fail:object? e)
                                  (regexp-match #rx"no such  
method" (exn-message e))
                                  (object-method-arity-includes? obj  
'forward-invocation (add1 (length args)))))
                           (lambda (x)
                             (printf "No such method: ~a for object ~a  
with args: ~a, forwarding.~%" 'name obj args)
                                     (send/apply exp forward- 
invocation 'name args))))
          (send/apply exp name args)))])))

 > (require (except-in scheme/class send))
   (require "test.scm")
   (send (new object%) ola)
. . test.scm:17:9: send/apply: no such method: ola for class: object%
 > (define a% (class object% (super-new) (define/public (forward- 
invocation name . args)
                                           (printf "Method: ~a args:  
~a~%" name args))))
   (send (new a%) hi)
No such method: hi for object #(struct:object:a% ...) with args: (),  
Method: hi args: ()

I'll test it better and integrate it tomorrow. If you have some  
comments please tell me, I'm a CLer and haven't got around the whole  
hygienic macro thing.


Posted on the users mailing list.