Атрибут “-doc” в Erlang/OTP вызывает ошибку в компиляторе.

Вопрос или проблема

Пытаюсь задокументировать функции в модуле 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 перед ним, что соответствует требованиям компилятора. Теперь при компиляции кода ошибки должны исчезнуть, и вы сможете правильно документировать ваши функции.

Оцените материал
Добавить комментарий

Капча загружается...