Вопрос или проблема
Пытаюсь задокументировать функции в модуле Erlang, но компилятор говорит, что мои атрибуты -doc
не могут находиться после функций. Конечно, они расположены после функций только тогда, когда они находятся перед другими функциями, поэтому я не понимаю ошибку.
Вот модуль:
-module(plb_ctl).
-moduledoc "Функции, общие для сервисов PLB.".
-export([is_node_running/1, start_node/3]).
-define(ERL_CMD, "erl -detached -noshell -name ~p -setcookie ~p").
-doc false.
log(Msg) -> io:format("~s~n", [Msg]).
-doc "Возвращает `true`, если узел работает на локальном хосте.".
-spec is_node_running(SName) -> true | false when
SName :: string().
is_node_running(SName) ->
SNames = element(2, net_adm:names()),
lists:any(fun(E) -> string:equal(element(1, E), SName) end, SNames).
-doc "Запускает отсоединенный узел на локальном хосте, если он еще не запущен.".
-spec start_node(SName, Name, Cookie) -> ok | no_return() when
SName :: string(),
Name :: string(),
Cookie :: string().
start_node(SName, Name, Cookie) ->
Cmd = io_lib:format(?ERL_CMD, [Name, Cookie]),
case is_node_running(SName) of
true -> log(SName ++ " уже запущен"), ok;
false -> case os:cmd(Cmd) of
[] -> log(SName ++ " запущен"), ok;
Msg -> throw({erl_cmd, io_lib:format("~s", [Msg])})
end
end.
Компиляция генерирует ошибки там, где появляются атрибуты -doc
:
plb_ctl.erl:11:2: атрибут doc после определения функций
% 11| -doc "Возвращает `true`, если узел работает на локальном хосте.".
% | ^
plb_ctl.erl:19:2: атрибут doc после определения функций
% 19| -doc "Запускает отсоединенный узел на локальном хосте, если он еще не запущен.".
% | ^
Обзор исходного кода Erlang/OTP показывает, что атрибут -doc
используется таким же образом, но я не могу сделать так, чтобы мой работал. Мне удалось найти источник сообщения в erl_lint.erl
, но я не могу понять, как он вызывается. На данный момент я вынужден закомментировать документацию.
Есть ли у кого-нибудь идеи, почему я получаю эти ошибки.
Ответ или решение
Проблема, с которой вы столкнулись, связана с порядком объявления атрибутов -doc
в вашем Erlang модуле. В Erlang существует строгий порядок, в котором следует объявлять атрибуты и функции.
Атрибуты -doc
, как и другие атрибуты (например, -spec
), должны предшествовать определению соответствующих функций. На данный момент в вашем коде атрибуты -doc
объявлены после определения функции, что вызывает ошибку компиляции.
Чтобы исправить проблему, вам нужно переместить атрибуты -doc
так, чтобы они шли перед определением каждой функции, вот исправленный код:
-module(plb_ctl).
-moduledoc "Functions common to PLB services.".
-export([is_node_running/1, start_node/3]).
-define(ERL_CMD, "erl -detached -noshell -name ~p -setcookie ~p").
-doc false.
log(Msg) -> io:format("~s~n", [Msg]).
-doc "Returns `true` if node is running on localhost.".
-spec is_node_running(SName) -> true | false when
SName :: string().
is_node_running(SName) ->
SNames = element(2, net_adm:names()),
lists:any(fun(E) -> string:equal(element(1, E), SName) end, SNames).
-doc "Starts a detached node on localhost if it is not already running.".
-spec start_node(SName, Name, Cookie) -> ok | no_return() when
SName :: string(),
Name :: string(),
Cookie :: string().
start_node(SName, Name, Cookie) ->
Cmd = io_lib:format(?ERL_CMD, [Name, Cookie]),
case is_node_running(SName) of
true -> log(SName ++ " already running"), ok;
false -> case os:cmd(Cmd) of
[] -> log(SName ++ " started"), ok;
Msg -> throw({erl_cmd, io_lib:format("~s", [Msg])})
end
end.
Таким образом, каждое определение функции имеет соответствующий атрибут -doc
и -spec
перед ним, что соответствует требованиям компилятора. Теперь при компиляции кода ошибки должны исчезнуть, и вы сможете правильно документировать ваши функции.