Часто возникает потребность в написании "похожего" кода для определенных случаев. Для этой цели существует инструкция META, которая позволяет создавать некий шаблон кода, называемый метакодом. В нем можно использовать параметры, которые затем будут заменяться на определенные значения при использовании этого метакода. Такой подход называется метапрограммирование.
Рассмотрим задачу создания простого справочника, как описано в статье How-to: CRUD.
1 2 | CLASS Book 'Книга';
name 'Наименование' = DATA ISTRING[30] (Book) IN id;
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | FORM book 'Книга' // форма для отображения "карточки" книги
OBJECTS b = Book PANEL
PROPERTIES(b) name
EDIT Book OBJECT b
;
FORM books 'Книги'
OBJECTS b = Book
PROPERTIES(b) READONLY name
PROPERTIES(b) NEWSESSION NEW, EDIT, DELETE
LIST Book OBJECT b
;
NAVIGATOR {
NEW books;
}
|
На основе этого программного кода можно создать следующий метакод :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | META defineObject(class, id, shortId, caption, multiCaption)
CLASS class caption;
TABLE id(class);
name 'Наименование' = DATA ISTRING[100] (class);
FORM id caption
OBJECTS shortId = class PANEL
PROPERTIES(shortId) name
EDIT class OBJECT shortId
;
FORM id##s multiCaption
OBJECTS shortId = class
PROPERTIES(shortId) READONLY name
PROPERTIES(shortId) NEWSESSION NEW, EDIT, DELETE
LIST class OBJECT shortId
;
NAVIGATOR {
NEW id##s;
}
END
META defineObject(id, shortId, caption, multiCaption)
@defineObject(###id, id, shortId, caption, multiCaption);
END
|
Важно отметить, что один метакод может внутри вызывать другой.
Использование метакода осуществляется следующим образом :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | META defineObject(class, id, shortId, caption, multiCaption)
CLASS class caption;
TABLE id(class);
name 'Наименование' = DATA ISTRING[100] (class);
FORM id caption
OBJECTS shortId = class PANEL
PROPERTIES(shortId) name
EDIT class OBJECT shortId
;
FORM id##s multiCaption
OBJECTS shortId = class
PROPERTIES(shortId) READONLY name
PROPERTIES(shortId) NEWSESSION NEW, EDIT, DELETE
LIST class OBJECT shortId
;
NAVIGATOR {
NEW id##s;
}
END
META defineObject(id, shortId, caption, multiCaption)
@defineObject(###id, id, shortId, caption, multiCaption);
END
|
В первом случае, при генерации результирующего кода система заменит все лексемы id на book, shortId на b, caption на 'Книга', а multiCaption на 'Книги'. При этом при использовании склейки ## замена будет произведена без изменений, а при использовании ### первая буква значения будет заменена на заглавную. Сгенерированный код будет выглядеть следующим образом :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | CLASS Book 'Книга';
TABLE book(Book);
name 'Наименование' = DATA ISTRING[100] (Book);
FORM book 'Книга'
OBJECTS b = Book PANEL
PROPERTIES(b) name
EDIT Book OBJECT b
;
FORM books 'Книги'
OBJECTS b = Book
PROPERTIES(b) READONLY name
PROPERTIES(b) NEWSESSION NEW, EDIT, DELETE
LIST Book OBJECT b
;
NAVIGATOR {
NEW books;
}
CLASS Magazine 'Журнал';
TABLE magazine(Magazine);
name 'Наименование' = DATA ISTRING[100] (Magazine);
FORM magazine 'Журнал'
OBJECTS m = Magazine PANEL
PROPERTIES(m) name
EDIT Magazine OBJECT m
;
FORM magazines 'Журналы'
OBJECTS m = Magazine
PROPERTIES(m) READONLY name
PROPERTIES(m) NEWSESSION NEW, EDIT, DELETE
LIST Magazine OBJECT m
;
NAVIGATOR {
NEW magazines;
}
|
Для того, чтобы IDE "видела" код сгенерированный метакодами, нужно включить соответствующий режим через пункт меню.
При включенном режиме работы с метакодами сгенерированный код будет автоматом подставляться в исходниках при его использовании.
Любые изменения в нем невозможны, так как будут автоматически затираться IDE. Однако, при коммите изменений в программе в систему контроля версий рекомендуется выключать этот режим, чтобы избежать ненужной истории изменений.
Объекты, созданные при помощи метакода, можно в дальнейшем расширять используя стандартные механизмы.
1 2 3 | genre 'Жанр' = DATA ISTRING[20] (Book);
EXTEND FORM book PROPERTIES(b) genre;
EXTEND FORM books PROPERTIES(b) genre;
|