Модуль поведение
Предоставляет функции для работы с модулями во время компиляции.
Это позволяет разработчику динамически добавлять, удалять и регистрировать атрибуты, прикреплять документацию и так далее.
После компиляции модуля, использование многих функций этого модуля вызовет ошибки, так как они не предназначены для проверки данных во время выполнения. Большинство данных во время выполнения можно проверить с помощью функции __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 автоматически ищет вызовы устаревших модулей и выводит предупреждения во время компиляции.
Использование атрибута @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 compile.elixir.
Если внешний ресурс не существует, модуль всё ещё имеет зависимость от него, что приводит к перекомпиляции модуля как только файл будет добавлен.
@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
Атрибуты структур
@derive— выводит реализацию для данного протокола для структуры, определенной в текущем модуле@enforce_keys— гарантирует, что заданные ключи всегда устанавливаются при построении структуры, определенной в текущем модуле
См. Kernel.defstruct/1 для получения дополнительной информации о создании и использовании структур.
Атрибуты типов спецификаций
Следующие атрибуты являются частью типов спецификаций и также являются встроенными в 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 - имя функции/макроса
- список скобочных аргументов
- список скобочных условий
- скобочное тело функции
Если функция/макрос, подлежащий определению, имеет несколько разделов, обратный вызов будет вызван для каждого раздела.
В отличие от других обратных вызовов, @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.get_compiler_option/1@compile {:debug_info, false}- отключает:debug_infoнезависимо от соответствующего параметра вCode.get_compiler_option/1@compile {:inline, some_fun: 2, other_fun: 3}- встраивает заданные пары имя/арность. Встраивание применяется локально, вызовы из другого модуля не затрагиваются этой опцией@compile {:autoload, false}- отключает автоматическую загрузку модулей после компиляции. Вместо этого модуль загрузится после его отправки@compile {:no_warn_undefined, Mod}или@compile {:no_warn_undefined, {Mod, fun, arity}}- не выдает предупреждение, если указанный модуль или указанныйMod.fun/arityне определены
Краткое описание
Обработчики событий
- __info__(atom)
Предоставляет информацию о времени выполнения функций, макросов и другой информации, определенной модулем.
Функции
- attributes_in(module)
Возвращает все имена атрибутов модуля, определенные в
module.- concat(list)
Конкатенирует список псевдонимов и возвращает новый псевдоним.
- concat(left, right)
Конкатенирует два псевдонима и возвращает новый псевдоним.
- create(module, quoted, opts)
Создает модуль с заданным именем и определенным заданными выражениями.
- defines_type?(module, definition)
Проверяет, определяет ли текущий модуль данный тип (приватный, непрозрачный или нет).
- defines?(module, tuple)
Проверяет, определяет ли модуль данную функцию или макрос.
- defines?(module, tuple, def_kind)
Проверяет, определяет ли модуль функцию или макрос данного
kind.- definitions_in(module)
Возвращает все функции и макросы, определенные в
module.- definitions_in(module, kind)
Возвращает все функции, определенные в
module, в соответствии с их типом.- delete_attribute(module, key)
Удаляет атрибут модуля, соответствующий заданному ключу.
- delete_definition(module, arg)
Удаляет определение из модуля.
- eval_quoted(module_or_env, quoted, binding \\ [], opts \\ [])
Вычисляет содержимое с котировкой в контексте данного модуля.
- get_attribute(module, key, default \\ nil)
Возвращает заданный атрибут из модуля.
- get_definition(module, arg, options \\ [])
Возвращает определение для заданной пары имя-арность.
- has_attribute?(module, key)
Проверяет, определен ли данный атрибут.
- make_overridable(module, tuples)
Делает указанные функции в
moduleпереопределяемыми.- open?(module)
Проверяет, открыт ли модуль.
- overridable?(module, tuple)
Возвращает
true, еслиtupleвmoduleбыл помечен как переопределяемый в какой-то момент.- overridables_in(module)
Возвращает все переопределяемые определения в
module.- put_attribute(module, key, value)
Добавляет атрибут модуля со значением
keyиvalueв заданномmodule.- register_attribute(module, attribute, options)
Регистрирует атрибут.
- reserved_attributes()
Возвращает информацию об атрибутах модуля, используемых Elixir.
- safe_concat(list)
Конкатенирует список псевдонимов и возвращает новый псевдоним только в том случае, если псевдоним уже был сохранен.
- safe_concat(left, right)
Конкатенирует два псевдонима и возвращает новый псевдоним только в том случае, если псевдоним уже был сохранен.
- spec_to_callback(module, definition)
Копирует заданный шаблон в качестве обработчика событий.
- split(module)
Разделяет заданное имя модуля на бинарные части.
Обработчики событий
__info__(atom)Source
@callback __info__(:attributes) :: keyword()
@callback __info__(:compile) :: [term()]
@callback __info__(:functions) :: keyword()
@callback __info__(:macros) :: keyword()
@callback __info__(:md5) :: binary()
@callback __info__(:module) :: module()
Предоставляет информацию о времени выполнения функций, макросов и другой информации, определенной модулем.
Каждый модуль получает функцию __info__/1, когда он компилируется. Функция принимает один из следующих элементов:
:attributes- список ключевых слов со всеми сохраненными атрибутами:compile- список данных компилятора:functions- список ключевых слов публичных функций и их арностей:macros- список ключевых слов публичных макросов и их арностей:md5- MD5 модуля:module- имя атома модуля
Функции
attributes_in(модуль)Source
@spec attributes_in(module()) :: [atom()]
Возвращает все имена атрибутов модуля, определённых в module.
Эта функция может быть использована только для модулей, которые ещё не были скомпилированы.
Примеры
defmodule Example do @foo 1 Module.register_attribute(__MODULE__, :bar, accumulate: true) :foo in Module.attributes_in(__MODULE__) #=> true :bar in Module.attributes_in(__MODULE__) #=> true end
concat(список)Source
@spec concat([binary() | atom()]) :: atom()
Конкатенирует список псевдонимов и возвращает новый псевдоним.
Обрабатывает двоичные данные и атомы.
Примеры
iex> Module.concat([Foo, Bar]) Foo.Bar iex> Module.concat([Foo, "Bar"]) Foo.Bar
concat(левый, правый)Source
@spec concat(binary() | atom(), binary() | atom()) :: atom()
Конкатенирует два псевдонима и возвращает новый псевдоним.
Обрабатывает двоичные данные и атомы.
Примеры
iex> Module.concat(Foo, Bar) Foo.Bar iex> Module.concat(Foo, "Bar") Foo.Bar
create(модуль, цитированное, опции)Source
@spec create(module(), Macro.t(), Macro.Env.t() | keyword()) ::
{:module, module(), binary(), term()} Создаёт модуль с заданным именем, определённый заданными цитированными выражениями.
Строка, где определяется модуль, и его файл обязательно должны быть переданы в качестве опций.
Возвращает кортеж вида {:module, module, binary, term} где module - имя модуля, binary - байткод модуля, и term - результат последнего выражения в 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_type?(модуль, определение)Source
@spec defines_type?(module(), definition()) :: boolean()
Проверяет, определяет ли текущий модуль данный тип (приватный, неявный или нет).
Эта функция доступна только для компилируемых модулей.
defines?(модуль, кортеж)Source
@spec 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?(модуль, кортеж, вид_определения)Source
@spec 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 definitions_in(модуль)Source
@spec 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(модуль, тип)Source
@spec 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(модуль, ключ)Source
@spec 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
delete_definition(модуль, аргумент)Source
@spec delete_definition(module(), definition()) :: boolean()
Удаляет определение из модуля.
Возвращает true, если определение существует и было удалено, иначе возвращает false.
eval_quoted(модуль_или_среда, цитированное, связывание \\ [], опции \\ [])Source
@spec 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(модуль, ключ, значение_по_умолчанию \\ nil)Source
@spec 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
get_definition(module, arg, options \\ [])Source
@spec get_definition(module(), definition(), keyword()) ::
{:v1, def_kind(), meta :: keyword(),
[
{meta :: keyword(), arguments :: [Macro.t()], guards :: [Macro.t()],
Macro.t()}
]
| nil} Возвращает определение для заданной пары имя-арность.
Возвращает кортеж с version, kind, определением metadata, и списком с каждой из клаузул. Каждая клауза — это четырёхэлементный кортеж с метаданными, аргументами, условиями и AST клаузы.
Клаузы возвращаются в представлении AST Elixir, но уже в расширенном и нормализованном виде. Это полезно для анализа кода, но их нельзя повторно вставить в модуль, так как при этом будет потерян контекст. Поскольку представление AST в основном внутреннее, оно имеет версионность и может изменяться в любое время. Поэтому используйте этот API с осторожностью.
Параметры
-
:nillify_clauses(с версии v1.13.0) — возвращаетnilвместо клаузул. Это полезно, когда требуется только получение типа и метаданных
has_attribute?(module, key)Source
@spec has_attribute?(module(), atom()) :: boolean()
Проверяет, определён ли заданный атрибут.
Атрибут считается определённым, если он был зарегистрирован с помощью register_attribute/3 или ему было присвоено значение. Если атрибут был удалён с помощью delete_attribute/2, он больше не считается определённым.
Эта функция может быть использована только для модулей, которые ещё не были скомпилированы.
Примеры
defmodule MyModule do @value 1 Module.register_attribute(__MODULE__, :other_value) Module.put_attribute(__MODULE__, :another_value, 1) Module.has_attribute?(__MODULE__, :value) #=> true Module.has_attribute?(__MODULE__, :other_value) #=> true Module.has_attribute?(__MODULE__, :another_value) #=> true Module.has_attribute?(__MODULE__, :undefined) #=> false Module.delete_attribute(__MODULE__, :value) Module.has_attribute?(__MODULE__, :value) #=> false end
make_overridable(module, tuples)Source
@spec make_overridable(module(), [definition()]) :: :ok
@spec make_overridable(module(), module()) :: :ok
Делает заданные функции в module переопределяемыми.
Переопределяемая функция определяется лениво, что позволяет разработчику настроить её. Подробнее см. Kernel.defoverridable/1.
После того, как функция или макрос помечены как переопределяемые, они больше не будут отображаться в definitions_in/1 и возвращать true, когда им передаётся defines?/2, пока не будет предоставлена другая реализация.
open?(module)Source
@spec open?(module()) :: boolean()
Проверяет, открыт ли модуль.
Модуль считается «открытым», если он в настоящее время определяется, и его атрибуты и функции могут быть изменены.
overridable?(module, tuple)Source
@spec overridable?(module(), definition()) :: boolean()
Возвращает true, если tuple в module был помечен как переопределяемый в какой-то момент.
Обратите внимание, что overridable?/2 возвращает true даже если определение уже переопределено. Чтобы узнать, существует ли определение или оно ожидается, используйте defines?/2.
overridables_in(module)Source
@spec overridables_in(module()) :: [atom()]
Возвращает все переопределяемые определения в module.
Обратите внимание, что определение включается даже если оно уже переопределено. Чтобы узнать, существует ли определение или оно ожидается, используйте defines?/2.
Эта функция может быть использована только для модулей, которые ещё не были скомпилированы.
Примеры
defmodule Example do def foo, do: 1 def bar, do: 2 defoverridable foo: 1, bar: 1 def foo, do: 3 [:bar, :foo] = Module.overridables_in(__MODULE__) |> Enum.sort() end
put_attribute(module, key, value)Source
@spec 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)Source
@spec 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
reserved_attributes()Source
Возвращает информацию об атрибутах модуля, используемых Elixir.
См. раздел «Атрибуты модулей» в документации модуля для получения дополнительной информации о каждом атрибуте.
Примеры
iex> map = Module.reserved_attributes() iex> Map.has_key?(map, :moduledoc) true iex> Map.has_key?(map, :doc) true
safe_concat(list)Source
@spec safe_concat([binary() | atom()]) :: atom()
Конкатенирует список псевдонимов и возвращает новый псевдоним только если псевдоним уже был использован.
Если псевдоним ещё не был использован, генерирует ошибку ArgumentError. Обрабатывает двоичные данные и атомы.
Примеры
iex> Module.safe_concat([List, Chars]) List.Chars
safe_concat(left, right)Source
@spec safe_concat(binary() | atom(), binary() | atom()) :: atom()
Конкатенирует два псевдонима и возвращает новый псевдоним только если псевдоним уже был использован.
Если псевдоним ещё не был использован, генерирует ошибку ArgumentError. Обрабатывает двоичные данные и атомы.
Примеры
iex> Module.safe_concat(List, Chars) List.Chars
spec_to_callback(module, definition)Source
@spec spec_to_callback(module(), definition()) :: boolean()
Копирует заданный спецификацию в качестве обратного вызова.
Возвращает true, если такая спецификация существует и она была скопирована как обратный вызов. Если функция, связанная со спецификацией, имеет документацию, определённую до вызова этой функции, документация также копируется.
split(module)Source
@spec 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"]
© 2012 Plataformatec
Licensed under the Apache License, Version 2.0.
https://hexdocs.pm/elixir/1.13.4/Module.html