[plt-scheme] Catch an unknown method error
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
>