6.7 KiB
Написание исходного кода
Набор рекомендаций по подходу к написанию, оформлению и форматированию исходного кода на Erlang.
Оформление
Предлагается в большинстве наиболее общих случаев руководствоваться рекомендациями, изложенными здесь. Кроме явно изложенного в этом документе приводится ещё пара рекомендаций.
Краткое описание модулей
В шапке каждого модуля приложений, за исключением специальных модулей (наборы тестов, заглушки, модули с очевидным назначением, например, содержащие исключительно релизацию application behaviour) хорошим тоном будет указывать небольшое описание того, зачем этот модуль нужен и что он делает, в свободной форме, на языке, понятном большинству разработчиков.
Краткое описание сложной логики
В случае, если по субъективному мнению автора или ревьюера некоторые фрагменты исходного кода содержат сложную для восприятия логику, несмотря на все прочие старания автора, предлагается оформлять такие фрагменты комментариями в свободной форме, содержащими описание этой логики на естественном языке.
Форматирование
В проекте и связанных с ним зависимостях применяется подход к форматированию, построенный на паре основных принципов:
- систематическая предсказуемая индентация, дружественная к текстовым редакторам;
- уровень вложенности выражения напрямую зависит от его глубины в синтаксическом дереве, при этом начало и окончание (когда применимо) всегда находятся на одном уровне индентации, а содержимое, в случае необходимости разбивки на строки, – на следующем.
Эти принципы по скромному мнению автора сих строк позволяют ускорить просмотр и восприятие кода благодаря построению систематической крупномасштабной структуры и близости к характерным для большинства распространённых языков принципам. Всё это в свою очередь позволяет с меньшими усилиями ориентироваться как в общей и так и в частной структуре, находить и реструктурировать отдельные фрагменты, снизить необходимость в чересчур длинных строках, которые неявно навязываются при использовании Erlang community guidelines.
Удачный по мнению автора пример:
-spec task_init(options()) -> {ok, tx_id(), Tx, Tx, timeout()} | {error, #error_info{}} when
Tx :: tx().
task_init(Args) ->
try
init_tx(Args)
catch Class:Reason ->
transform_error(Class, Reason, erlang:get_stacktrace())
end.
init_tx({start, Initiator, Args}) ->
Static = static_manager:get_last_version(),
Handler = get_tx_handler(Initiator, Args),
Tx0 = prepare_tx(Handler:init_tx(Args, Static)),
Tx = processing_metric:db_do_write(
create_tx,
fun () ->
Tx1 = create_tx(approve(Tx0)),
case genlib_map:get(Initiator, genlib_map:get(contractors, Tx1)) of
undefined ->
Tx1;
Contractor ->
update_tx(bind_contractor(Initiator, Contractor, Tx1), Tx1)
end
end
),
construct_task_init_result(Tx).
Более конкретные детали, на которые стоит обратить внимание:
- размер индентации равен 4 пробелам;
- комфортная длина строк строго не регламентируется, максимальная равна 120 символам.
Прочие рекомендации, явно не упомянутые выше:
- блоки выражений, которые для простоты восприятия приходится отделять пустыми строками, возможно вместо этого лучше вынести в отдельные функции.
Работа с существующим кодом
При возникновении конфликтов с принятым в рамках модуля подходом к форматированию предлагается пересиливать себя что есть мочи и придерживаться оригинального подхода, чтобы исключить комбинирование разных подходов в рамках одного и того же модуля. Иначе в конечном итоге жизнь усложниться и у коллег по команде, и у самого автора внесённых неподобающим образом изменений.
При создании же новых модулей – хозяин барин.
Исключения
Кроме того, чтобы каждому занятому в проекте программисту было более комфортно, из каждого принципа допускаются незначительные исключения. Список может пополняться.
На текущий момент:
- Каждый может придерживаться комфортной для него лично длины строк, если она не превышает максимальной.