epp

epp — препроцессор, занимающийся раскрытием макросов и вставкой инклюдов.

epp содержит функции, которые используются компилятором. Эти функции организованы в модуль epp.

Если интересно увидеть работу препроцессора, можно использовать команду такого рода: compile:file(proba, ['P']). Здесь proba — название нашего модуля и, соответственно, файла (proba.erl).

Ради эксперимента создадим файл vstavka.hrl со следующим содержанием:

-record(stud, {age=18, name, lang="Erlang"}).

today() ->
    io:format("Hello! My name is ~p.~n", [?MODULE]),
    date(). 

Первая строка определяет запись stud. Также мы определили функцию today/0, которая делает то же самое, что и date/0, то есть возвращает сегодняшнюю дату. Вставлять этот файл будем в модуль proba:

-module(proba).
-export([main/0]).
-include("vstavka.hrl").

main() -> 
    io:format("Hello! I am ~p.~n", [?MODULE]),
    io:format("Today ~p.~n", [today()]).

Выполняем команду compile:file(proba, ['P']). или erlc -P proba.erl, чтобы посмотреть работу препроцессора: как он вставит инклюд и как заменит ?MODULE. В результате получается промежуточный файл proba.P следующего содержания:

-file("proba.erl", 1).

-module(proba).

-export([main/0]).

-file("vstavka.hrl", 1).

-record(stud,{age = 18, name, lang = "Erlang"}).

today() ->
    io:format("Hello! My name is ~p.~n", [proba]),
    date().

-file("proba.erl", 4).

main() ->
    io:format("Hello! I am ~p.~n", [proba]),
    io:format("Today ~p.~n", [today()]).

В результате работы препроцессора появились директивы -file, которые показывают, из какого файла взяты следующие несколько строчек кода. Второй аргумент — номер строки в данном файле, откуда начато чтение.

В этом файле нас интересуют четыре момента: как вставилась запись, как вставилась функция, как раскрылся макрос, раскрылся ли макрос во вставленном куске. По первым двум пунктам: vstavka.hrl вставился, вот и всё. Вместо макроса ?MODULE появилось в коде proba. Это появилось и там и там: где оригинальный кусок кода и где вставка. То есть сначала происходит вставка, а потом уже раскрытие макросов.

Чтобы запустить эту программу, надо её сначала нормально скомпилировать (до конца).

1> compile:file(proba, ['P']).
{ok,[]}
2> c(proba).
{ok,proba}
3> proba:main().
Hello! I am proba.
Hello! My name is proba.
Today {2024,3,11}.
ok

Документация

epp.


© Алексей Карманов, 2024.