I just noticed something: next-method *already* supports calling it with
different arguments. It's just not documented.

(define-class <foo> ())
(define-class <bar> (<foo>))

(define-method (f (self <foo>) (x <number>))
    (format #t "foo: ~a\n" x))

(define-method (f (self <bar>) (x <number>))
    (next-method self (1+ x))  ;; change arguments
    (format #t "bar: ~a\n" x))

(f (make <bar>) 1)

=>
foo: 2
bar: 1




On 21 April 2013 18:05, Tobias Brandt <tob.bra...@gmail.com> wrote:

> Hi,
>
> thanks for your input. I tried to avoid the whole next-method issue
> entirely and defined a method for make on bar's metaclass instead.
>
> (use-modules (oop goops))
>
> (define-class <foo> () (s #:init-keyword #:s))
> (define-class <bar-class> (<class>))
> (define-class <bar> (<foo>) #:metaclass <bar-class>)
>
> (define-method (make (self <bar-class>) (i <integer>))
>     (make self #:s (number->string i)))
>
> Now we can do:
>
> (slot-ref (make <bar> 1) 's)
> => "1"
>
> Old constructor still works (it has to, because it's called in the method
> we just defined):
>
> (slot-ref (make <bar> #:s "baz") 's)
> => "baz"
>
>
> However, I have no idea what the performance implications of creating a
> new metaclass are. IIRC, in Smalltalk every class has its own metaclass
> automatically and that doesn't seem to cause any problems.
>
>
> Regards,
> Tobias
>
>
>
> On 20 April 2013 00:58, Panicz Maciej Godek <godek.mac...@gmail.com>wrote:
>
>> Hey,
>> I've been trying to make some deeper inquiry. It turns out that the case
>> is not as simple as I thought.
>> I came up with the following function
>> (use-modules (oop goops) (ice-9 match) (srfi srfi-1))
>>
>> (define (parent-methods method class)
>>   (let* ((supers (class-direct-supers class))
>>          (super? (lambda(c)(find (lambda(s)(eq? c s)) supers))))
>>     (filter-map (match-lambda((method (? super? super) args ...) method)
>> (else #f))
>>  (map (lambda(m)(cons m (method-specializers m)))
>>                      (generic-function-methods method)))))
>>
>> it works more or less as expected, at least for initializers (because it
>> is defined in such way that it only looks at the method's first argument)
>> -- it does return a list of parents' initializers.
>>
>> The problem appears if a parent's initializer contains (next-method)
>> invocation. Otherwise (if there's no call to (next-method)) the method
>> contains a procedure in its 'procedure' slot, which can be accessed using
>> `method-procedure`, and then called or applied in a regular manner.
>> However, if there is a call to (next-method) in a macro, the
>> `method-procedure` called on such method returns #f. I think the idea is
>> that methods are meant to be called from the context of `apply-generic` and
>> next-method is a continuation, but I haven't figured out how it works
>> exactly.
>> Anyway, the thing isn't as simple as I thought and perhaps someone else
>> could try another approach.
>>
>> Sorry for causing confusion!
>> M.
>>
>
>

Reply via email to