Skip to main content
Version: 4.x

How-to: Metaprogramming

You may often need to write "similar" code for certain cases. The META statement exists for this purpose, and makes it possible to create a code template or metacode. It can contain parameters that will be replaced by certain values when this metacode is used. Such an approach is called metaprogramming.

Let's create a simple directory as described in the article. How-to: CRUD.

CLASS Book 'Book';
name 'Name' = DATA ISTRING[30] (Book) IN id;
FORM book 'Book' // form for displaying "card' // form for displaying the book card
OBJECTS b = Book PANEL
PROPERTIES(b) name

EDIT Book OBJECT b
;

FORM books 'Books'
OBJECTS b = Book
PROPERTIES(b) READONLY name
PROPERTIES(b) NEWSESSION NEW, EDIT, DELETE

LIST Book OBJECT b
;

NAVIGATOR {
NEW books;
}

We can use this code to write the following metacode:

META defineObject(class, id, shortId, caption, multiCaption)
CLASS class caption;
TABLE id(class);

name '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

Note that one code segment can programmatically call another one.

This is how metacode is used:

@defineObject(book, b, 'Book', 'Books');
@defineObject(magazine, m, 'Magazine', 'Magazines');

In the first case, when the system starts generating the result code, it will replace all id lexemes with book, shortId with b, caption with 'Book', and multiCaption with 'Books'. When using ## concatenation, these replacements will leave everything unchanged. If ### concatenation is used, the first letter of the value will be capitalized. The generated code will look like this:

CLASS Book 'Book';
TABLE book(Book);

name 'Name' = DATA ISTRING[100] (Book);

FORM book 'Book'
OBJECTS b = Book PANEL
PROPERTIES(b) name

EDIT Book OBJECT b
;

FORM books 'Books'
OBJECTS b = Book
PROPERTIES(b) READONLY name
PROPERTIES(b) NEWSESSION NEW, EDIT, DELETE

LIST Book OBJECT b
;

NAVIGATOR {
NEW books;
}

CLASS Magazine 'Magazine';
TABLE magazine(Magazine);

name 'Name' = DATA ISTRING[100] (Magazine);

FORM magazine 'Magazine'
OBJECTS m = Magazine PANEL
PROPERTIES(m) name

EDIT Magazine OBJECT m
;

FORM magazines 'Magazines'
OBJECTS m = Magazine
PROPERTIES(m) READONLY name
PROPERTIES(m) NEWSESSION NEW, EDIT, DELETE

LIST Magazine OBJECT m
;

NAVIGATOR {
NEW magazines;
}

In order for the IDE to "see" the code generated by metacodes, you need to enabled the corresponding mode in the menu.

When the metacode support mode is enabled, the generated code will be automatically substituted in the source code if metacode is used.

Any modifications of the code will be impossible, since they will be automatically overwritten by the IDE. However, it is recommended to disable this mode when committing code to your version control system to avoid creating redundant change history entries.

Objects created using metacode can subsequently be extended using standard mechanisms.

genre 'Genre' = DATA ISTRING[20] (Book);
EXTEND FORM book PROPERTIES(b) genre;
EXTEND FORM books PROPERTIES(b) genre;