Spec-Zone.ru › Elixir 1.6

Правила именования

В данном документе рассматриваются некоторые правила именования кода на 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 также включает четыре специальных формы, которые следуют формату с двумя нижними подчеркиваниями. Эти формы извлекают информацию о текущей среде на стадии компиляции: __MODULE__/0, __DIR__/0, __ENV__/0 и __CALLER__/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

Также существуют некоторые функции без пар, без варианта без восклицательного знака. Восклицательный знак всё равно указывает на то, что в случае неудачи будет выброшено исключение. Примеры: Mix.Config.validate!/1, 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. Мы подробно рассмотрим эти случаи ниже.

length и size

Когда вы видите 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.6.6/naming-conventions.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API