Модуль behaviour
Предоставляет функции для работы с модулями во время компиляции.
Это позволяет разработчику динамически добавлять, удалять и регистрировать атрибуты, прикреплять документацию и т. д.
После компиляции модуля использование многих функций в этом модуле вызовет ошибки, так как они не предназначены для проверки данных во время выполнения. Большинство данных во время выполнения можно проверить через функцию __info__/1, прикрепленную к каждому скомпилированному модулю.
Атрибуты модуля
Каждый модуль может быть снабжён одним или несколькими атрибутами. Следующие из них в настоящее время определены в Elixir:
@after_compile
Обработчик, который вызывается сразу после компиляции текущего модуля. Принимает модуль или {module, function_name}. См. раздел «Обработчики компиляции» ниже.
@before_compile
Обработчик, который вызывается перед компиляцией модуля. Принимает модуль или {module, function_or_macro_name} кортеж. См. раздел «Обработчики компиляции» ниже.
@behaviour
Обратите внимание на британское написание!
Модули могут ссылаться на поведения, чтобы гарантировать, что они реализуют требуемые сигнатуры функций, определённые @callback.
Например, вы можете указать поведение URI.Parser, как показано ниже:
defmodule URI.Parser do @doc "Defines a default port" @callback default_port() :: integer @doc "Parses the given URL" @callback parse(uri_info :: URI.t()) :: URI.t() end
И затем модуль может использовать его так:
defmodule URI.HTTP do @behaviour URI.Parser def default_port(), do: 80 def parse(info), do: info end
Если поведение изменится или URI.HTTP не реализует один из образов обработки, будет выведено предупреждение.
@impl
Для помощи в правильной реализации поведения вы можете необязательно объявить @impl для реализованных образов обработки поведения. Это делает образы обработки явными и может помочь обнаружить ошибки в вашем коде. Компилятор выдаст предупреждения в этих случаях:
-
если вы помечаете функцию
@impl, когда эта функция не является обратом обработки. -
если вы не помечаете функцию
@impl, когда другие функции помечены@impl. Если вы помечаете одну функцию@impl, вы должны пометить все другие образы обработки для этого поведения как@impl.
@impl работает на основе контекста. Если вы генерируете функцию с помощью макроса и помечаете её @impl, это не повлияет на модуль, в котором эта функция генерируется.
@impl также способствует поддержке, делая понятным для других разработчиков, что функция реализует обратный вызов.
Используя @impl, вышеприведённый пример можно переписать как:
defmodule URI.HTTP do @behaviour URI.Parser @impl true def default_port(), do: 80 @impl true def parse(info), do: info end
Вы можете передать либо false, true, или конкретное поведение в @impl.
defmodule Foo do @behaviour Bar @behaviour Baz # Will warn if neither Bar nor Baz specify a callback named bar/0. @impl true def bar(), do: :ok # Will warn if Baz does not specify a callback named baz/0. @impl Baz def baz(), do: :ok end
Код теперь более читабелен, так как теперь ясно, какие функции являются частью вашего API, а какие — реализациями обратных вызовов. Для усиления этой идеи @impl true автоматически помечает функцию как @doc false, отключая документацию, если @doc не задан явно.
@compile
Определяет параметры для компиляции модуля. Это используется для настройки как Elixir, так и Erlang компиляторов, а также любых других этапов компиляции, добавленных сторонними инструментами. Например:
defmodule MyModule do
@compile {:inline, my_fun: 1}
def my_fun(arg) do
to_string(arg)
end
end Несколько применений @compile будут накапливаться, а не перезаписывать предыдущие. См. раздел «Параметры компиляции» ниже.
@deprecated
Предоставляет причину устаревания функции. Например:
defmodule Keyword do
@deprecated "Use Kernel.length/1 instead"
def size(keyword) do
length(keyword)
end
end Компилятор Mix автоматически ищет вызовы устаревших модулей и выводит предупреждения во время компиляции, вычисленные с помощью mix xref warnings.
Использование атрибута @deprecated также будет отражено в документации данной функции и макроса. Вы можете выбрать между атрибутом @deprecated и метаданными документации, чтобы обеспечить жёсткую устарелость (с предупреждениями) и мягкую устарелость (без предупреждений):
Это мягкая устарелость, так как она просто аннотирует документацию как устаревшую:
@doc deprecated: "Use Kernel.length/1 instead" def size(keyword)
Это жёсткая устарелость, так как она выводит предупреждения и аннотирует документацию как устаревшую:
@deprecated "Use Kernel.length/1 instead" def size(keyword)
В настоящее время @deprecated поддерживает только функции и макросы. Однако вы можете использовать ключ :deprecated в метаданных аннотаций, чтобы аннотировать документацию модулей, типов и обратных вызовов.
Мы рекомендуем использовать эту функцию с осторожностью, особенно авторам библиотек. Устаревание кода всегда перекладывает бремя на пользователей библиотек. Мы также рекомендуем поддерживать устаревшую функциональность в течение длительного времени даже после устаревания, давая разработчикам достаточно времени для обновления (за исключением случаев, когда сохранение устаревшего API нежелательно, например, при наличии проблем с безопасностью).
@doc и @typedoc
Предоставляет документацию для сущности, которая следует за атрибутом. @doc используется с функцией, макросом, обратным вызовом или макро-обратным вызовом, а @typedoc с типом (публичным или неявным).
Принимает строку (часто heredoc) или false, где @doc false сделает сущность невидимой для инструментов извлечения документации, таких как ExDoc. Например:
defmodule MyModule do
@typedoc "This type"
@typedoc since: "1.1.0"
@type t :: term
@doc "Hello world"
@doc since: "1.1.0"
def hello do
"world"
end
@doc """
Sums `a` to `b`.
"""
def sum(a, b) do
a + b
end
end Как видно из примера, @doc и @typedoc также принимают список ключевых слов, который служит способом предоставления произвольных метаданных о сущности. Инструменты, такие как ExDoc и IEx, могут использовать эту информацию для отображения аннотаций. Распространённый случай — since, который может использоваться для аннотирования версии, в которой была введена функция.
Как показано в примере, можно использовать эти атрибуты более одного раза перед сущностью. Однако компилятор выдаст предупреждение, если они будут использованы дважды с двоичными данными, поскольку это заменит текст документации из предыдущего использования. Несколько применений со списками ключевых слов объединят списки в один.
Обратите внимание, что, поскольку компилятор также определяет некоторые дополнительные метаданные, есть несколько зарезервированных ключей, которые будут игнорироваться и вызовут предупреждение при использовании. В настоящее время это: :opaque и :defaults.
После компиляции модуля эта информация становится доступной через функцию Code.fetch_docs/1.
@dialyzer
Определяет предупреждения для запроса или подавления при использовании версии :dialyzer, которая поддерживает атрибуты модулей.
Принимает атом, кортеж или список атомов и кортежей. Например:
defmodule MyModule do
@dialyzer {:nowarn_function, my_fun: 1}
def my_fun(arg) do
M.not_a_function(arg)
end
end Список поддерживаемых предупреждений см. в :dialyzer модуле.
Несколько применений @dialyzer будут накапливаться, а не перезаписывать предыдущие.
@external_resource
Указывает внешний ресурс для текущего модуля.
Иногда модуль встраивает информацию из внешнего файла. Этот атрибут позволяет модулю аннотировать используемые внешние ресурсы.
Инструменты, такие как Mix, могут использовать эту информацию, чтобы убедиться, что модуль перекомпилируется в случае изменения внешних ресурсов.
@file
Изменяет имя файла, используемое в стековых следах для функции или макроса, за которым следует атрибут, например:
defmodule MyModule do
@doc "Hello world"
@file "hello.ex"
def hello do
"world"
end
end @moduledoc
Предоставляет документацию для текущего модуля.
defmodule MyModule do @moduledoc """ A very useful module. """ @moduledoc authors: ["Alice", "Bob"] end
Принимает строку (часто heredoc) или false, где @moduledoc false сделает модуль невидимым для инструментов извлечения документации, таких как ExDoc.
Аналогично @doc, также принимает список ключевых слов для предоставления метаданных о модуле. Более подробную информацию см. в документации @doc выше.
После компиляции модуля эта информация становится доступной через функцию Code.fetch_docs/1.
@on_definition
Обработчик, который вызывается при определении каждой функции или макроса в текущем модуле. Полезно при аннотировании функций.
Принимает модуль или {module, function_name} кортеж. См. раздел «Обработчики компиляции» ниже.
@on_load
Обработчик, который вызывается при каждом загрузке модуля.
Принимает имя функции (в качестве атома) функции в текущем модуле или {function_name, 0} кортеж, где function_name — имя функции в текущем модуле. Функция должна быть публичной и иметь арность 0 (без аргументов). Если функция не возвращает :ok, загрузка модуля будет прервана. Например:
defmodule MyModule do
@on_load :load_check
def load_check do
if some_condition() do
:ok
else
:abort
end
end
def some_condition do
false
end
end Модули, скомпилированные с HiPE, не будут вызывать этот обработчик.
@vsn
Укажите версию модуля. Принимает любое допустимое значение Elixir, например:
defmodule MyModule do @vsn "1.0" end
Атрибуты типов
Следующие атрибуты являются частью спецификаций типов и также встроенные в Elixir:
-
@type- определяет тип, используемый в@spec -
@typep- определяет закрытый тип, используемый в@spec -
@opaque- определяет неявный тип, используемый в@spec -
@spec- предоставляет спецификацию для функции -
@callback- предоставляет спецификацию для обратного вызова поведения -
@macrocallback- предоставляет спецификацию для макро-обратного вызова поведения -
@optional_callbacks- указывает, какие обратные вызовы поведения и макро-обратные вызовы поведения являются необязательными -
@impl- объявляет реализацию функции обратного вызова или макроса
Пользовательские атрибуты
Помимо встроенных атрибутов, перечисленных выше, можно также добавить пользовательские атрибуты. Пользовательские атрибуты выражаются с помощью оператора @/1, за которым следует допустимое имя переменной. Значение, заданное для пользовательского атрибута, должно быть допустимым значением Elixir:
defmodule MyModule do @custom_attr [some: "stuff"] end
Дополнительные параметры, доступные при определении пользовательских атрибутов, см. в register_attribute/3.
Обработчики компиляции
Существует три обработчика, которые вызываются при определении функций, а также до и сразу после генерации байткода модуля.
@after_compile
Обработчик, который вызывается сразу после компиляции текущего модуля.
Принимает модуль или {module, function_name} кортеж. Функция должна принимать два аргумента: среду модуля и его байткод. Если указан только модуль, функция предполагается __after_compile__/2.
Обработчики, зарегистрированные первыми, будут выполняться последними.
Пример
defmodule MyModule do
@after_compile __MODULE__
def __after_compile__(env, _bytecode) do
IO.inspect(env)
end
end @before_compile
Обработчик, который будет вызван перед компиляцией модуля.
Принимает модуль или кортеж {module, function_or_macro_name}. Функция/макрос должны принимать один аргумент: среду модуля. Если это макрос, его возвращаемое значение будет вставлено в конец определения модуля перед началом компиляции.
Когда предоставляется только модуль, функция/макрос предполагается __before_compile__/1.
Обработчики, зарегистрированные первыми, будут выполняться последними. Любое переопределяемое определение будет конкретизировано до запуска первого обработчика. Определение может быть снова сделано переопределяемым в другом обработчике до компиляции, и оно будет окончательно конкретизировано после того, как будут выполнены все обработчики.
Примечание: в отличие от @after_compile, функция/макрос обратного вызова должны быть размещены в отдельном модуле (потому что когда вызывается обратный вызов, текущий модуль еще не существует).
Пример
defmodule A do
defmacro __before_compile__(_env) do
quote do
def hello, do: "world"
end
end
end
defmodule B do
@before_compile A
end
B.hello()
#=> "world" @on_definition
Обработчик, который будет вызван при определении каждой функции или макроса в текущем модуле. Полезно при аннотировании функций.
Принимает модуль или кортеж {module, function_name}. Функция должна принимать 6 аргументов:
- среда модуля
- тип функции/макроса:
:def,:defp,:defmacro, или:defmacrop - имя функции/макроса
- список процитированных аргументов
- список процитированных условий
- процитированный тело функции
Обратите внимание, что обработчик получает процитированные аргументы, и он вызывается до того, как функция хранится в модуле. Таким образом, Module.defines?/2 вернет false для первого раздела каждой функции.
Если определяемая функция/макрос имеет несколько разделов, обработчик будет вызываться для каждого раздела.
В отличие от других обработчиков, @on_definition будет вызывать только функции и никогда не макросы. Это делается для предотвращения @on_definition вызовов от переопределения функций, которые были только что определены в пользу более явных подходов.
Когда предоставляется только модуль, функция предполагается __on_definition__/6.
Пример
defmodule Hooks do
def on_def(_env, kind, name, args, guards, body) do
IO.puts("Defining #{kind} named #{name} with args:")
IO.inspect(args)
IO.puts("and guards")
IO.inspect(guards)
IO.puts("and body")
IO.puts(Macro.to_string(body))
end
end
defmodule MyModule do
@on_definition {Hooks, :on_def}
def hello(arg) when is_binary(arg) or is_list(arg) do
"Hello" <> to_string(arg)
end
def hello(_) do
:ok
end
end Параметры компиляции
Атрибут @compile принимает различные параметры, используемые как компилятором Elixir, так и компилятором Erlang. Некоторые из распространённых случаев использования описаны ниже:
-
@compile :debug_info- включает:debug_infoнезависимо от соответствующей настройки вCode.compiler_options/1 -
@compile {:debug_info, false}- отключает:debug_infoнезависимо от соответствующей настройки вCode.compiler_options/1 -
@compile {:inline, some_fun: 2, other_fun: 3}- встраивает заданные пары имя/арность. Встраивание применяется локально, вызовы из другого модуля не затрагиваются этим параметром -
@compile {:autoload, false}- отключает автоматическую загрузку модулей после компиляции. Вместо этого модуль будет загружен после его отправки
Вы можете увидеть ещё несколько параметров, используемых компилятором Erlang, в документации для :compile модуля.
Обзор
Функции
- concat(список)
Конкатенирует список псевдонимов и возвращает новый псевдоним.
- concat(левый, правый)
Конкатенирует два псевдонима и возвращает новый псевдоним.
- create(модуль, процитированные, параметры)
Создаёт модуль с заданным именем и определённый заданными процитированными выражениями.
- defines?(модуль, кортеж)
Проверяет, определяет ли модуль заданную функцию или макрос.
- defines?(модуль, кортеж, тип_определения)
Проверяет, определяет ли модуль функцию или макрос заданного
kind.- defines_type?(модуль, определение)
Проверяет, определяет ли текущий модуль заданный тип (приватный, неявный или нет).
- definitions_in(модуль)
Возвращает все функции и макросы, определённые в
module.- definitions_in(модуль, тип_определения)
Возвращает все функции, определённые в
module, согласно их типу.- delete_attribute(модуль, ключ)
Удаляет атрибут модуля, соответствующий заданному ключу.
- eval_quoted(модуль_или_среда, процитированные, привязки \\ [], параметры \\ [])
Вычисляет процитированное содержимое в контексте заданного модуля.
- get_attribute(модуль, ключ, значение_по_умолчанию \\ nil)
Получает заданный атрибут из модуля.
- make_overridable(модуль, кортежи)
Делает заданные функции в
moduleпереопределяемыми.- open?(модуль)
Проверяет, открыт ли модуль.
- overridable?(модуль, кортеж)
Возвращает
true, еслиtupleвmoduleпомечен как переопределяемый.- put_attribute(модуль, ключ, значение)
Добавляет атрибут модуля со
keyиvalueв заданномmodule.- register_attribute(модуль, атрибут, параметры)
Регистрирует атрибут.
- safe_concat(список)
Конкатенирует список псевдонимов и возвращает новый псевдоним только в том случае, если псевдоним уже был ссылался.
- safe_concat(левый, правый)
Конкатенирует два псевдонима и возвращает новый псевдоним только в том случае, если псевдоним уже был ссылался.
- spec_to_callback(модуль, определение)
Копирует заданный спектр как обратный вызов.
- split(модуль)
Разделяет заданное имя модуля на бинарные части.
Обратные вызовы
- __info__(атом)
Предоставляет runtime-информацию о функциях, макросах и другой информации, определённой модулем.
Функции
concat(list)
Характеристики
concat([binary() | atom()]) :: atom()
Конкатенирует список псевдонимов и возвращает новый псевдоним.
Примеры
iex> Module.concat([Foo, Bar]) Foo.Bar iex> Module.concat([Foo, "Bar"]) Foo.Bar
concat(left, right)
Характеристики
concat(binary() | atom(), binary() | atom()) :: atom()
Конкатенирует два псевдонима и возвращает новый псевдоним.
Примеры
iex> Module.concat(Foo, Bar) Foo.Bar iex> Module.concat(Foo, "Bar") Foo.Bar
create(module, quoted, opts)
Характеристики
create(module(), Macro.t(), Macro.Env.t() | keyword()) ::
{:module, module(), binary(), term()} Создаёт модуль с заданным именем и определённый заданными выражениями в кавычках.
Строка, где модуль определён, и его файл должны быть переданы в качестве опций.
Возвращает кортеж формы {:module, module, binary, term}, где binary — имя модуля, term — байткод модуля и quoted — результат последнего выражения в quoted.
Аналогично Kernel.defmodule/2, бинарный файл будет записан на диск только как файл .beam, если Module.create/3 вызывается в файле, который в данный момент компилируется.
Примеры
contents =
quote do
def world, do: true
end
Module.create(Hello, contents, Macro.Env.location(__ENV__))
Hello.world()
#=> true Отличия от defmodule
Module.create/3 работает аналогично Kernel.defmodule/2 и возвращает те же результаты. Хотя можно также использовать defmodule для динамического определения модулей, эта функция предпочтительнее, когда тело модуля задано выражением в кавычках.
Другое важное различие состоит в том, что Module.create/3 позволяет контролировать переменные среды, используемые при определении модуля, в то время как Kernel.defmodule/2 автоматически использует среду, в которой он вызван.
defines?(module, tuple)
Характеристики
defines?(module(), definition()) :: boolean()
Проверяет, определяет ли модуль данную функцию или макрос.
Используйте defines?/3, чтобы проверить тип.
Эта функция может быть использована только для модулей, которые ещё не были скомпилированы. Используйте Kernel.function_exported?/3 и Kernel.macro_exported?/3, чтобы проверить наличие публичных функций и макросов соответственно в скомпилированных модулях.
Обратите внимание, что defines? возвращает false для функций и макросов, которые были определены, но затем помечены как переопределяемые, и ни одна другая реализация не была предоставлена. Вы можете проверить статус переопределяемости, вызвав overridable?/2.
Примеры
defmodule Example do
Module.defines?(__MODULE__, {:version, 0}) #=> false
def version, do: 1
Module.defines?(__MODULE__, {:version, 0}) #=> true
end defines?(module, tuple, def_kind)
Характеристики
defines?(module(), definition(), def_kind()) :: boolean()
Проверяет, определяет ли модуль функцию или макрос заданного kind.
kind может быть любым из :def, :defp, :defmacro, или :defmacrop.
Эта функция может быть использована только для модулей, которые ещё не были скомпилированы. Используйте Kernel.function_exported?/3 и Kernel.macro_exported?/3, чтобы проверить наличие публичных функций и макросов соответственно в скомпилированных модулях.
Примеры
defmodule Example do
Module.defines?(__MODULE__, {:version, 0}, :def) #=> false
def version, do: 1
Module.defines?(__MODULE__, {:version, 0}, :def) #=> true
end defines_type?(module, definition)
Характеристики
defines_type?(module(), definition()) :: boolean()
Проверяет, определяет ли текущий модуль заданный тип (приватный, неявный или нет).
Эта функция доступна только для модулей, которые компилируются.
definitions_in(module)
Характеристики
definitions_in(module()) :: [definition()]
Возвращает все функции и макросы, определённые в module.
Возвращает список всех определённых функций и макросов, публичных и приватных, в форме [{name, arity}, ...].
Эта функция может быть использована только для модулей, которые ещё не были скомпилированы. Используйте обратный вызов Module.__info__/1, чтобы получить публичные функции и макросы в скомпилированных модулях.
Примеры
defmodule Example do
def version, do: 1
defmacrop test(arg), do: arg
Module.definitions_in(__MODULE__) #=> [{:version, 0}, {:test, 1}]
end definitions_in(module, def_kind)
Характеристики
definitions_in(module(), def_kind()) :: [definition()]
Возвращает все функции, определённые в module, в соответствии с его типом.
Эта функция может быть использована только для модулей, которые ещё не были скомпилированы. Используйте обратный вызов Module.__info__/1, чтобы получить публичные функции и макросы в скомпилированных модулях.
Примеры
defmodule Example do
def version, do: 1
Module.definitions_in(__MODULE__, :def) #=> [{:version, 0}]
Module.definitions_in(__MODULE__, :defp) #=> []
end delete_attribute(module, key)
Характеристики
delete_attribute(module(), atom()) :: term()
Удаляет атрибут модуля, соответствующий заданному ключу.
Возвращает значение удалённого атрибута (или nil если ничего не было установлено).
Примеры
defmodule MyModule do Module.put_attribute(__MODULE__, :custom_threshold_for_lib, 10) Module.delete_attribute(__MODULE__, :custom_threshold_for_lib) end
eval_quoted(module_or_env, quoted, binding \\ [], opts \\ [])
Характеристики
eval_quoted( module() | Macro.Env.t(), Macro.t(), list(), keyword() | Macro.Env.t() ) :: term()
Вычисляет содержимое в кавычках в контексте данного модуля.
В качестве аргумента также можно передать список опций среды. Смотрите Code.eval_string/3 для получения дополнительной информации.
Вызывает ошибку, если модуль уже был скомпилирован.
Примеры
defmodule Foo do
contents =
quote do
def sum(a, b), do: a + b
end
Module.eval_quoted(__MODULE__, contents)
end
Foo.sum(1, 2)
#=> 3 Для удобства вы можете передать любую структуру Macro.Env, такую как __ENV__/0, в качестве первого аргумента или в качестве опций. Как модуль, так и все опции будут автоматически извлечены из среды:
defmodule Foo do
contents =
quote do
def sum(a, b), do: a + b
end
Module.eval_quoted(__ENV__, contents)
end
Foo.sum(1, 2)
#=> 3 Обратите внимание, что если вы передаёте структуру Macro.Env в качестве первого аргумента, а также передаёте opts, они будут объединены, причём opts имеет приоритет.
get_attribute(module, key, default \\ nil)
Характеристики
get_attribute(module(), atom(), term()) :: term()
Получает заданный атрибут из модуля.
Если атрибут был помечен с помощью accumulate с помощью Module.register_attribute/3, всегда возвращается список. nil возвращается, если атрибут не был помечен с помощью accumulate и не был установлен ни на какое значение.
Макрос @ компилируется в вызов этой функции. Например, следующий код:
@foo
Расширяется до чего-то, что напоминает:
Module.get_attribute(__MODULE__, :foo)
Эта функция может быть использована только для модулей, которые ещё не были скомпилированы. Используйте обратный вызов Module.__info__/1, чтобы получить все сохранённые атрибуты, или Code.fetch_docs/1, чтобы получить все атрибуты, относящиеся к документации, в скомпилированных модулях.
Примеры
defmodule Foo do Module.put_attribute(__MODULE__, :value, 1) Module.get_attribute(__MODULE__, :value) #=> 1 Module.get_attribute(__MODULE__, :value, :default) #=> 1 Module.get_attribute(__MODULE__, :not_found, :default) #=> :default Module.register_attribute(__MODULE__, :value, accumulate: true) Module.put_attribute(__MODULE__, :value, 1) Module.get_attribute(__MODULE__, :value) #=> [1] end
make_overridable(module, tuples)
Характеристики
make_overridable(module(), [definition()]) :: :ok
make_overridable(module(), module()) :: :ok
Делает заданные функции в module переопределяемыми.
Переопределяемая функция определяется лениво, позволяя разработчику её настроить. Смотрите Kernel.defoverridable/1 для получения дополнительной информации и документации.
После того, как функция или макрос помечены как переопределяемые, они больше не будут отображаться в definitions_in/1 или возвращать true при передаче в defines?/2, пока не будет предоставлена другая реализация.
open?(module)
Характеристики
open?(module()) :: boolean()
Проверяет, открыт ли модуль.
Модуль «открыт», если он в данный момент определяется, и его атрибуты и функции могут быть изменены.
overridable?(module, tuple)
Характеристики
overridable?(module(), definition()) :: boolean()
Возвращает true, если tuple в module помечен как переопределяемый.
put_attribute(module, key, value)
Характеристики
put_attribute(module(), atom(), term()) :: :ok
Устанавливает атрибут модуля с key и value в заданный module.
Примеры
defmodule MyModule do Module.put_attribute(__MODULE__, :custom_threshold_for_lib, 10) end
register_attribute(module, attribute, options)
Характеристики
register_attribute(module(), atom(), accumulate: boolean(), persist: boolean()) :: :ok
Регистрирует атрибут.
Регистрируя атрибут, разработчик может настроить, как Elixir будет хранить и накапливать значения атрибутов.
Опции
При регистрации атрибута можно указать две опции:
-
:accumulate— несколько вызовов одного и того же атрибута будут накапливаться вместо переопределения предыдущего. Новые атрибуты всегда добавляются в начало накопленного списка. -
:persist— атрибут будет сохранён в формате Erlang Abstract Format. Полезно при взаимодействии с Erlang-библиотеками.
По умолчанию обе опции false.
Примеры
defmodule MyModule do Module.register_attribute(__MODULE__, :custom_threshold_for_lib, accumulate: true) @custom_threshold_for_lib 10 @custom_threshold_for_lib 20 @custom_threshold_for_lib #=> [20, 10] end
safe_concat(list)
Спецификации
safe_concat([binary() | atom()]) :: atom()
Конкатенирует список псевдонимов и возвращает новый псевдоним только в случае, если псевдоним уже был использован.
Если псевдоним еще не использовался, возникает ошибка ArgumentError. Обрабатывает списки символов, двоичные данные и атомы.
Примеры
iex> Module.safe_concat([Module, Unknown]) ** (ArgumentError) argument error iex> Module.safe_concat([List, Chars]) List.Chars
safe_concat(left, right)
Спецификации
safe_concat(binary() | atom(), binary() | atom()) :: atom()
Конкатенирует два псевдонима и возвращает новый псевдоним только в случае, если псевдоним уже был использован.
Если псевдоним еще не использовался, возникает ошибка ArgumentError. Обрабатывает списки символов, двоичные данные и атомы.
Примеры
iex> Module.safe_concat(Module, Unknown) ** (ArgumentError) argument error iex> Module.safe_concat(List, Chars) List.Chars
spec_to_callback(module, definition)
Спецификации
spec_to_callback(module(), definition()) :: boolean()
Копирует заданную спецификацию в качестве обратного вызова.
Возвращает true если такая спецификация существует и была скопирована как обратный вызов. Если функции, связанной со спецификацией, было определено описание до вызова этой функции, документация также копируется.
split(module)
Спецификации
split(module() | String.t()) :: [String.t(), ...]
Разделяет заданное имя модуля на двоичные части.
module должен быть модулем Elixir, так как split/1 не будет работать с модулями в стиле Erlang (например, split(:lists) вызывает ошибку).
split/1 также поддерживает разделение строкового представления модулей Elixir (то есть результата вызова Atom.to_string/1 с именем модуля).
Примеры
iex> Module.split(Very.Long.Module.Name.And.Even.Longer)
["Very", "Long", "Module", "Name", "And", "Even", "Longer"]
iex> Module.split("Elixir.String.Chars")
["String", "Chars"] Обратные вызовы
__info__(atom)
Спецификации
__info__(:attributes) :: keyword()
__info__(:compile) :: [term()]
__info__(:functions) :: keyword()
__info__(:macros) :: keyword()
__info__(:md5) :: binary()
__info__(:module) :: module()
Предоставляет информацию о функциях, макросах и другой информации, определенной в модуле.
Каждый модуль получает функцию __info__/1 при компиляции. Функция принимает один из следующих элементов:
-
:attributes- список ключевых слов со всеми сохраненными атрибутами -
:compile- список с метаданными компилятора -
:functions- список ключевых слов общедоступных функций и их арностей -
:macros- список ключевых слов общедоступных макросов и их арностей -
:md5- MD5 модуля -
:module- имя атома модуля
© 2012 Plataformatec
Licensed under the Apache License, Version 2.0.
https://hexdocs.pm/elixir/1.9.4/Module.html