Spec-Zone.ru › Elixir 1.8

Протокол

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

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

Функции

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

Spec-Zone.ru

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