Регистрация | Войти
Lisp — программируемый язык программирования
RSS
restas:defun-context
necto - 01.04.2013 11:06, Сообщений - 1
Предлагаю такое расширение restas :inherit-parent-context.

Специальный вид функций, которые используют динамический контекст модуля, пусть пока называются контекстно зависимые. Определяются в модуле с помощью restas:context-defun. Например в модуле guest-book:

(restas:context-defun get-feedback-url ()
   (if *e-mail*
      (restas:genurl* 'feedback)
      (format nil "Ваши отзывы и предложения присылайте на наш АЯ: Совесткая 1")
)
)

Эта функция использует динамическую переменную модуля guest-book:*e-mail*, и более того, генерирует ссылку на страницу модуля guest-book:feedback.

Если эту функцию напрямую вызвать из родительского модуля, то значение guest-book:*e-mail*, будет не тем, которое было передано при монтировании модуля:

(in-package :main)

(restas:mount-module 'gb (#:guest-book)
   (:inherit-parent-content t)
   (guest-book:*e-mail* t)
)



но благодаря тому, что она определена как контекстно-зависимая (restas:context-defun) После монтирования модуля, автоматически генерируется функция main:gb.get-feedback-url. Которая при вызове настраивает контекст дочернего модуля:

(defun gb.get-feedback-url ()
   (let ((restas:*module* (restas:find-module 'gb)))
     (restas:with-module-context *module*
        (guest-book::get-feedback-url)
)
)
)

       

Эти функции тоже добавляются в список контекстно зависимых и при монтировании модуля main, для низ будут созданы соответствующие обертки на следующем уровне.

Так мы получаем возможность дергать функции из подмодулей. Остаётся проблема передачи функция из одного подмодуля данного модуля main, другому. Для этого можно определять значения gb.get-feedback-url таким образом:

(defparam gb.get-feedback-url
  (lambda ()
    (let ((restas:*module* (restas:get-parent *module*)))
      (let ((restas:*module* (restas:find-module 'gb)))
        (restas:with-module-context *module*
          (guest-book::get-feedback-url)
)
)
)
)
)

       

 Тогда можно будет передавать их следующим образом при монтировании второго ребенка:

(restas:mount-module m1 (#:module-one)
   (module-one:*fb-callback* gb.get-feedback-url)
)
Благодаря тому, что у нас 2 пространства имен - функций и переменных, возможно одновременное хранение этих двух функций. Тогда (funcall *fb-callback*) из m1 будет тоже правильно перенастраивать контекст перед вызовом оригинальной guest-book:get-feedback-url.

Ваши мысли, товарищи?
P. S. как лучше назвать restas:context-defun?




[#]
> Ваши мысли, товарищи?

Слишком сложно. И потенциально слишком много кодогенерации. Я думаю, что лучше сделать макрос with-module-context, которому указывается символ смонтированного модуля (возможно, цепочки смонтированных модулей).
archimag - 01.04.2013 11:25
@2009-2013 lisper.ru