Лицензия Creative Commons
Содержимое блога доступно по лицензии Creative Commons Атрибуция — С сохранением условий
(Attribution-ShareAlike) 3.0 Unported
, если не указано иное.

воскресенье, 14 апреля 2013 г.

Макрос define-method* для использования ключевых слов совместно с GOOPS

Сегодня загрузил в репозиторий LazyCat коммит, который добавляет макрос, расширяющий стандартный набор функций GOOPS для создания методов. Макрос используется для реализации метода host-list-add-host в классе <host-list> и позволяет использовать ключевые слова (англ. keywords) для задания аргументов, передаваемых в метод. То есть, вместо создания методов с большим количеством параметров, или выдёргивания аргументов из списка по индексу, можно просто указывать каждый из аргументов по ключевому слову.

Текущая версия макроса выглядит так:

;; Needed modules
(use-modules (ice-9 optargs)
             (ice-9 syncase)
             (oop goops))

;; Macro definition
(define-syntax define-method*
  (syntax-rules ()
    ((_ (m (o <class>) (var defval) ...) body ...)
     (define-method (m (o <class>) . args)
       (let-keywords args #t ((var defval) ...)
                     body ...)))))

Пример использования макроса:

(define-class <talking-machine> ())

(define-method* (hey (obj <talking-machine>)
                     (say  "Hello, ") 
                     (name "J. Random Programmer"))
  (display (string-append say name "!\n")))

(define talking-machine (make <talking-machine>))

Результат вызова метода hey с разными аргументами:

(hey talking-machine)
=> Hello, J. Random Programmer!

(hey talking-machine #:say "Goodbye, ")
=> Goodbye, J. Random Programmer!

(hey talking-machine #:name "John Doe")
=> Hello, John Doe!

Данный макрос написан в процессе изучения макросов в GNU Guile -- может быть, данную задачу можно решить гораздо более простым и элегантным способом?

- Артём