Skip to end of metadata
Go to start of metadata

Часто возникает потребность в написании "похожего" кода для определенных случаев. Для этой цели существует инструкция 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;

  • No labels