Протокол
Функции для работы с протоколами.
Краткое описание
Функции
- 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.7.4/Protocol.html