[plt-scheme] Catch an unknown method error
Filipe Cabecinhas wrote:
>
> 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
>>
>>
Catching the exception doesn't tell you whether the immediate 'send'
referred to a non-existing method or if the method did exist but some
other 'send' failed during the execution of the method.
Use 'method-in-interface?' and 'object-interface' instead to check the
existence of the method before doing the call. Or use
'object-method-arity-includes?' again if you also want to forward on
arity mismatch.
Revised code below.
> 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).
>
> code:
>
Here's my version:
(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 ...)])
(if (and (not (method-in-interface? 'name (object-interface obj)))
(object-method-arity-includes? obj 'forward-invocation
(add1 (length args))))
(begin
(printf "No such method: ~a for object ~a with args: ~a,
forwarding.~%"
'name obj args)
(send/apply obj forward-invocation 'name args))
(send/apply obj name args)))])))
Ryan
>
>
> > (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: (),
> forwarding.
> 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.
>
>
> F
>
>
>
> _________________________________________________
> For list-related administrative tasks:
> http://list.cs.brown.edu/mailman/listinfo/plt-scheme