[Devel-conf] Metalterator: pattern syntax
Pavel Wolneykien
manowar на altlinux.org
Пн Апр 13 19:06:01 MSD 2009
Всем привет, :)
При использовании (alterator metalterator) и ajax.scm возникает (по
крайней мере у меня возник) соблазн вовсе не использовать промежуточный
бакенд. Это, наверное, нормальная реакция человеческого организма на
многозвенную архитектуру. Но я не стал этого делать. А вместо этого
постарался отвести бакенду достойную роль.
Получилось у меня следующее.
1. Бакенд закрывает метабакенд от произвольного к нему доступа.
Ведь через метабакенд можно читать и писать произвольные объекты, в
том числе, и не предусмотренные конкретным модулем Альтератора.
Кроме лишних объектов метабакенду можно отправить и просто
некорректные (с точки зрения работы конкретного модуля) данные. А
проверкой данных на корректность у нас тоже традиционно
занимается бакенд.
2. Бакенд отвечает на запросы "type" и производит другого рода
проверку корректности данных.
А ещё в интерфейс часто нужно выводить какой-либо набор констант,
причём с комментариями на местном языке. Для этой цели тоже можно
использовать бакенд.
3. Бакенд отвечает на запросы о константах.
Вторая и третья задача решаются традиционными способами, а первая
требует непропорционально увесистого куска кода: использовать большой
набор условных операторов перед проксированием операции чтения/записи в
метабакенд (где она, фактически, и будет выполнена) показалось мне
скучным. Поскольку речь идёт об определении некоторого шаблона, через
который определённые вызовы проходили бы, а определённые -- нет
(выдавалось бы сообщение об ошибке), то я придумал набор макросов,
позволяющий описать такой шаблон в более компактном виде.
Называется он woo-case.
Формат его вызова такой:
(woo-case (список_объектов список_параметров)
((имя_операции_1 (шаблон_объектов_1) [(шаблон_параметров_1)])
вычисление_1 ...)
((имя_операции_2 (шаблон_объектов_2) [(шаблон_параметров_2)])
вычисление_2 ...)
...
else вычисление_по_умолчанию)
Шаблон объектов используется при выполнении двух действий:
сличения списка объектов и захвата параметров.
Вместо того, чтобы просто обозначить в шаблоне место, где могут
находится одно
('squid 'groups ? 'domains ?)
или более имён
('squid 'groups *)
можно обозначить эти пропуски символами, а затем использовать эти
символы в программе:
('squid 'groups @g 'domains @d)
после сличения, например, с таким списком: ('squid 'groups "wheel"
'domains "altlinux"), переменные @g и @d примут значения "wheel" и
"altlinux" соответственно. Шаблонный параметр вида @имя захватывает 1
значение, а вида @@имя одно и более значений.
Шаблон параметров, в отличие от шаблона объектов, может быть опущен, а
при его наличии он используется только для захвата параметров, но не для
сличения. Поэтому порядок перечисления параметров в шаблоне параметров
произвольный. Поскольку каждый параметр в списке параметров однозначно
связан с впередистоящим именем, то параметр вида @@имя используется для
захвата всех значений одного параметра, а вида @имя -- для захвата
только 1, первого значения. Например, шаблон
('http_port @p 'auth-mode @a 'internal-ifaces @@e 'mode @m)
сохранит под именем @@e все значения параметра 'internal-ifaces, а
значение параметра 'mode он не "съест".
В том случае, если какой либо из обозначенных параметров не был
указан, то значение соответствующей переменной будет равно #f.
И последнее, но немаловажное: если какая-либо переменная вида @имя
(или @@имя) уже была определена в результате предыдущей операции
сличения/захвата, то в следующем шаблоне будет использовано _её
значение_. Таким образом, во вложенных конструкциях woo-case можно
использовать значения, определённые внешними шаблонами -- получатся
контекстно-зависимые шаблоны.
Павел.
Подробная информация о списке рассылки devel-conf