Правила именования
В данном документе описаны некоторые правила именования в коде Elixir, от стилей написания до знаков препинания.
Стиль написания
Разработчики Elixir должны использовать snake_case при определении переменных, имён функций, атрибутов модулей и т. п.:
some_map = %{this_is_a_key: "and a value"}
is_map(some_map)
Исключение составляют псевдонимы, часто используемые в качестве имён модулей, которые должны быть написаны с заглавной буквы и в CamelCase, например, OptionParser. В псевдонимах заглавные буквы сохраняются в аббревиатурах, например, ExUnit.CaptureIO или Mix.SCM.
Атомы могут быть написаны как в :snake_case , так и в :CamelCase, хотя в Elixir принято использовать вариант с нижним подчеркиванием.
Как правило, имена файлов следуют snake_case соглашению о именовании модулей, которые они определяют. Например, MyApp должен быть определён внутри файла my_app.ex. Однако это всего лишь соглашение. В конечном итоге, можно использовать любое имя файла, так как они никак не влияют на скомпилированный код.
Подчеркивание (_foo)
Elixir использует подчеркивания в различных ситуациях.
Например, значение, которое не должно использоваться, должно быть присвоено _ или переменной, начинающейся с подчеркивания:
iex> {:ok, _contents} = File.read("README.md")
Имена функций также могут начинаться с подчеркивания. Такие функции никогда не импортируются по умолчанию:
iex> defmodule Example do ...> def _wont_be_imported do ...> :oops ...> end ...> end iex> import Example iex> _wont_be_imported() ** (CompileError) iex:1: undefined function _wont_be_imported/0
Благодаря этому свойству, Elixir использует функции, начинающиеся с подчеркивания, для добавления метаданных на этапе компиляции в модули. Такие функции чаще всего имеют формат __foo__. Например, каждый модуль в Elixir имеет функцию __info__/1:
iex> String.__info__(:functions) [at: 2, capitalize: 1, chunk: 2, ...]
Elixir также включает пять специальных форм, которые следуют формату с двумя подчеркиваниями: __CALLER__/0, __DIR__/0, __ENV__/0 и __MODULE__/0 извлекают информацию о текущей среде на этапе компиляции, в то время как __STACKTRACE__/0 извлекает стек вызовов для текущего исключения.
Заключительный восклицательный знак (foo!)
Заключительный восклицательный знак указывает на функцию или макрос, в которых случаи неудачи вызывают исключение.
Многие функции представлены парами, например, File.read/1 и File.read!/1. File.read/1 возвращает кортеж успеха или неудачи, тогда как File.read!/1 возвращает простое значение или же вызывает исключение:
iex> File.read("file.txt")
{:ok, "file contents"}
iex> File.read("no_such_file.txt")
{:error, :enoent}
iex> File.read!("file.txt")
"file contents"
iex> File.read!("no_such_file.txt")
** (File.Error) could not read file no_such_file.txt: no such file or directory
Версия без ! предпочтительнее, когда вы хотите обрабатывать различные результаты с помощью сопоставления с образцом:
case File.read(file) do
{:ok, body} -> # do something with the `body`
{:error, reason} -> # handle the error caused by `reason`
end
Однако, если вы ожидаете, что результат всегда будет успешным (например, если вы ожидаете, что файл всегда существует), вариант с восклицательным знаком может быть удобнее и выведет более информативное сообщение об ошибке (чем неудачное сопоставление с образцом) при неудаче.
Ещё примеры парных функций: Base.decode16/2 и Base.decode16!/2, File.cwd/0 и File.cwd!/0.
Также есть некоторые функции без пар, без варианта без восклицательного знака. Восклицательный знак всё ещё означает, что при неудаче будет вызвано исключение. Пример: Protocol.assert_protocol!/1.
В коде макросов восклицательный знак в Kernel.alias!/1 и Kernel.var!/2 означает, что отложена проверка корректности макроса.
Заключительный вопросительный знак (foo?)
Функции, возвращающие булево значение, имеют в названии заключительный вопросительный знак.
Примеры: Keyword.keyword?/1, Mix.debug?/0, String.contains?/2
Однако функции, возвращающие булевы значения и допустимые в условиях, следуют другому соглашению, которое описано ниже.
Префикс is_ (is_foo)
Проверки типа и другие проверки на булевы значения, разрешённые в условиях, имеют префикс is_.
Примеры: Integer.is_even/1, Kernel.is_list/1
Эти функции и макросы следуют соглашению Erlang с префиксом is_, а не заключительным вопросительным знаком, именно для обозначения того, что они разрешены в условиях.
Обратите внимание, что проверки типа, которые не допустимы в условиях, не следуют этому соглашению. Примеры: Keyword.keyword?/1, Regex.regex?/1
Специальные имена
Некоторые имена имеют особое значение в Elixir. Мы подробнее рассмотрим эти случаи ниже.
длина и размер
Когда вы видите size в имени функции, это означает, что операция выполняется за постоянное время (также записывается как «O(1) время»), потому что размер хранится вместе со структурой данных.
Примеры: Kernel.map_size/1, Kernel.tuple_size/1
Когда вы видите length, операция выполняется за линейное время («O(n) время»), потому что вся структура данных должна быть пройдена.
Примеры: Kernel.length/1, String.length/1
Другими словами, функции, использующие слово «размер» в своём имени, будут выполняться за одинаковое время, независимо от того, мала или велика структура данных. Напротив, функции, имеющие «длину» в своём имени, будут работать дольше по мере увеличения размера структуры данных.
© 2012 Plataformatec
Licensed under the Apache License, Version 2.0.
https://hexdocs.pm/elixir/1.10.4/naming-conventions.html