Spec-Zone.ru › Elixir 1.6

Протокол

Функции для работы с протоколами.

Краткое описание

Функции

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

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API