Протокол
Функции для работы с протоколами.
Краткое описание
Функции
- assert_impl!(protocol, base)
Проверяет, загружен ли данный модуль и является ли он реализацией данного протокола.
- assert_protocol!(module)
Проверяет, загружен ли данный модуль и является ли он протоколом.
- consolidate(protocol, types)
Получает протокол и список реализаций и консолидирует данный протокол.
- consolidated?(protocol)
Возвращает
true, если протокол был консолидирован.- def(signature)
Определяет новую функцию протокола.
- derive(protocol, module, options \\ [])
Выводит
protocolдляmoduleс заданными параметрами.- extract_impls(protocol, paths)
Извлекает все типы, реализующие данный протокол, из заданных путей.
- extract_protocols(paths)
Извлекает все протоколы из заданных путей.
Функции
assert_impl!(protocol, base)
assert_impl!(module(), module()) :: :ok
Проверяет, загружен ли данный модуль и является ли он реализацией данного протокола.
Возвращает :ok, если это так, в противном случае вызывает ArgumentError.
assert_protocol!(module)
assert_protocol!(module()) :: :ok
Проверяет, загружен ли данный модуль и является ли он протоколом.
Возвращает :ok, если это так, в противном случае вызывает ArgumentError.
consolidate(protocol, types)
consolidate(module(), [module()]) ::
{:ok, binary()} | {:error, :not_a_protocol} | {:error, :no_beam_info} Получает протокол и список реализаций и консолидирует данный протокол.
Консолидация происходит путем изменения протокола impl_for в абстрактном формате для быстрого поиска. Обычно список реализаций для использования во время консолидации извлекается с помощью extract_impls/2.
Возвращает обновленную версию байткода протокола. Если первый элемент кортежа является :ok, это означает, что протокол был консолидирован.
Заданный байткод или реализация протокола могут быть проверены на консолидацию или нет путем анализа атрибута протокола:
Protocol.consolidated?(Enumerable)
Эта функция не загружает протокол ни на каком этапе и не загружает новый байткод для скомпилированного модуля. Однако каждая реализация должна быть доступна и будет загружена.
consolidated?(protocol)
consolidated?(module()) :: boolean()
Возвращает true, если протокол был консолидирован.
def(signature)
(макрос) Определяет новую функцию протокола.
Протоколы не позволяют определять функции напрямую, вместо этого стандартные Kernel.def/* макросы заменяются этим макросом, который определяет функции протокола с соответствующими обратными вызовами.
derive(protocol, module, options \\ [])
(макрос) Выводит protocol для module с заданными параметрами.
Если ваша реализация передает параметры или если вы генерируете пользовательский код на основе структуры, вам также необходимо реализовать макрос, определенный как __deriving__(module, struct, options), чтобы получить параметры, которые были переданы.
Примеры
defprotocol Derivable do
def ok(a)
end
defimpl Derivable, for: Any do
defmacro __deriving__(module, struct, options) do
quote do
defimpl Derivable, for: unquote(module) do
def ok(arg) do
{:ok, arg, unquote(Macro.escape(struct)), unquote(options)}
end
end
end
end
def ok(arg) do
{:ok, arg}
end
end
defmodule ImplStruct do
@derive [Derivable]
defstruct a: 0, b: 0
defimpl Sample do
def ok(struct) do
Unknown.undefined(struct)
end
end
end Явные выводы теперь могут вызываться через __deriving__:
# Explicitly derived via `__deriving__`
Derivable.ok(%ImplStruct{a: 1, b: 1})
# Explicitly derived by API via `__deriving__`
require Protocol
Protocol.derive(Derivable, ImplStruct, :oops)
Derivable.ok(%ImplStruct{a: 1, b: 1}) extract_impls(protocol, paths)
extract_impls(module(), [charlist() | String.t()]) :: [atom()]
Извлекает все типы, реализующие данный протокол, из заданных путей.
Пути могут быть либо списком символов, либо строкой. Внутренне с ними работают как со списками символов, поэтому передача их как списков избегает лишнего преобразования.
Не загружает ни одну из реализаций.
Примеры
# Get Elixir's ebin directory path and retrieve all protocols iex> path = :code.lib_dir(:elixir, :ebin) iex> mods = Protocol.extract_impls(Enumerable, [path]) iex> List in mods true
extract_protocols(paths)
extract_protocols([charlist() | String.t()]) :: [atom()]
Извлекает все протоколы из заданных путей.
Пути могут быть либо списком символов, либо строкой. Внутренне с ними работают как со списками символов, поэтому передача их как списков избегает лишнего преобразования.
Не загружает ни один из протоколов.
Примеры
# Get Elixir's ebin directory path and retrieve all protocols iex> path = :code.lib_dir(:elixir, :ebin) iex> mods = Protocol.extract_protocols([path]) iex> Enumerable in mods true
© 2012 Plataformatec
Licensed under the Apache License, Version 2.0.
https://hexdocs.pm/elixir/1.8.2/Protocol.html