Протокол
Функции для работы с протоколами.
Краткое описание
Функции
- 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 | no_return()
Проверяет, загружен ли данный модуль и является ли он реализацией данного протокола.
Возвращает :ok в случае успеха, в противном случае вызывает ArgumentError.
assert_protocol!(module)
assert_protocol!(module()) :: :ok | no_return()
Проверяет, загружен ли данный модуль и является ли он протоколом.
Возвращает :ok в случае успеха, в противном случае вызывает ArgumentError.
consolidate(protocol, types)
consolidate(module(), [module()]) ::
{:ok, binary()} | {:error, :not_a_protocol} | {:error, :no_beam_info} Принимает протокол и список реализаций и консолидирует данный протокол.
Консолидация происходит путем изменения протокола impl_for в абстрактном формате для обеспечения быстрых правил поиска. Обычно список реализаций для использования во время консолидации извлекается с помощью extract_impls/2.
Возвращает обновленную версию байткода протокола. Можно проверить, консолидирован ли данный байткод или реализация протокола, проанализировав атрибут протокола:
Protocol.consolidated?(Enumerable)
Если первый элемент кортежа равен true, это означает, что протокол был консолидирован.
Эта функция не загружает протокол ни на каком этапе, а также не загружает новый байткод для скомпилированного модуля. Однако каждая реализация должна быть доступна, и она будет загружена.
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 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 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.6.6/Protocol.html