[plt-scheme] Catch an unknown method error

From: Matthias Felleisen (matthias at ccs.neu.edu)
Date: Thu Feb 21 08:47:49 EST 2008

Ah of course.



On Feb 21, 2008, at 8:43 AM, Ryan Culpepper wrote:

> 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
>



Posted on the users mailing list.