Spec-Zone.ru › Elixir 1.4

Запись

Модуль для работы с записями, определения и импорта записей.

Записи — это просто кортежи, где первый элемент — атом:

iex> Record.is_record {User, "john", 27}
true

Этот модуль предоставляет удобства для работы с записями во время компиляции, где имена полей времени компиляции используются для управления кортежами, обеспечивая быстрые операции над компактной структурой кортежей.

В Elixir записи в основном используются в двух ситуациях:

  1. для работы с короткими внутренними данными
  2. для взаимодействия с записями Erlang

Макросы defrecord/3 и defrecordp/3 могут использоваться для создания записей, а extract/2 и extract_all/1 могут использоваться для извлечения записей из файлов Erlang.

Типы

Типы могут быть определены для кортежей с помощью макроса record/2 (доступен только в описаниях типов). Этот макрос будет расширяться до кортежа, как показано в примере ниже:

defmodule MyModule do
  require Record
  Record.defrecord :user, name: "john", age: 25

  @type user :: record(:user, name: String.t, age: integer)
  # expands to: "@type user :: {:user, String.t, integer}"
end

Обзор

Функции

defrecord(name, tag \\ nil, kv)

Определяет набор макросов для создания, доступа и сопоставления с образцом записи

defrecordp(name, tag \\ nil, kv)

То же, что и defrecord/3, но генерирует приватные макросы

extract(name, opts)

Извлекает информацию о записи из файла Erlang

extract_all(opts)

Извлекает всю информацию о записях из файла Erlang

is_record(data)

Проверяет, является ли данная data записью

is_record(data, kind)

Проверяет, является ли данная data записью типа kind

Функции

defrecord(name, tag \\ nil, kv) (макрос)

Определяет набор макросов для создания, доступа и сопоставления с образцом записи.

Имя сгенерированных макросов будет name (должно быть атомом). tag также является атомом и используется в качестве «тега» для записи (то есть, первого элемента кортежа записи); по умолчанию (если nil), он совпадает с name. kv — это список ключевых слов полей name: default_value для новой записи.

Генерируются следующие макросы:

  • name/0 для создания новой записи с значениями по умолчанию для всех полей
  • name/1 для создания новой записи с заданными полями и значениями, для получения индекса (с нуля) заданного поля в записи или для преобразования заданной записи в список ключевых слов
  • name/2 для обновления существующей записи с заданными полями и значениями или для доступа к заданному полю в заданной записи

Все эти макросы являются публичными (как определено defmacro).

Примеры использования этих макросов см. в разделе «Примеры».

Примеры

defmodule User do
  require Record
  Record.defrecord :user, [name: "meg", age: "25"]
end

В примере выше будет определен набор макросов с именем user, но с различными арностью для управления базовой записью.

# Import the module to make the user macros locally available
import User

# To create records
record = user()        #=> {:user, "meg", 25}
record = user(age: 26) #=> {:user, "meg", 26}

# To get a field from the record
user(record, :name) #=> "meg"

# To update the record
user(record, age: 26) #=> {:user, "meg", 26}

# To get the zero-based index of the field in record tuple
# (index 0 is occupied by the record "tag")
user(:name) #=> 1

# Convert a record to a keyword list
user(record) #=> [name: "meg", age: 26]

Сгенерированные макросы также могут использоваться для сопоставления с образцом записей и привязки переменных во время сопоставления:

record = user() #=> {:user, "meg", 25}

user(name: name) = record
name #=> "meg"

По умолчанию Elixir использует имя записи в качестве первого элемента кортежа (тега). Однако можно указать другой тег при определении записи:

defmodule User do
  require Record
  Record.defrecord :user, User, name: nil
end

require User
User.user() #=> {User, nil}

Определение извлеченных записей с анонимными функциями в значениях

Если запись определяет анонимную функцию в значениях по умолчанию, будет поднято исключение ArgumentError. Это может произойти непреднамеренно при определении записи после ее извлечения из библиотеки Erlang, использующей анонимные функции по умолчанию.

Record.defrecord :my_rec, Record.extract(...)
#=> ** (ArgumentError) invalid value for record field fun_field,
cannot escape #Function<12.90072148/2 in :erl_eval.expr/5>.

Чтобы обойти эту ошибку, переопределите поле с вашей собственной функцией &M.f/a, как показано ниже:

defmodule MyRec do
  require Record
  Record.defrecord :my_rec, Record.extract(...) |> Keyword.merge(fun_field: &__MODULE__.foo/2)
  def foo(bar, baz), do: IO.inspect({bar, baz})
end

defrecordp(name, tag \\ nil, kv) (макрос)

То же, что и defrecord/3, но генерирует приватные макросы.

extract(name, opts)

Извлекает информацию о записи из файла Erlang.

Возвращает выражение с котировкой, содержащее поля в виде списка кортежей.

name, имя извлеченной записи, должно быть атомом во время компиляции.

Параметры

Эта функция принимает следующие параметры, которые являются взаимоисключающими (т.е., только один из них может быть использован в одном вызове):

  • :from — (двоичное представление пути к файлу) путь к файлу Erlang, содержащий определение записи для извлечения; с этим параметром функция использует тот же поиск путей, что и атрибут -include в модулях Erlang.
  • :from_lib — (двоичное представление пути к файлу) путь к файлу Erlang, содержащий определение записи для извлечения; с этим параметром функция использует тот же поиск путей, что и атрибут -include_lib в модулях Erlang.

Ожидается, что эти параметры будут литералами (включая двоичные значения) во время компиляции.

Примеры

iex> Record.extract(:file_info, from_lib: "kernel/include/file.hrl")
[size: :undefined, type: :undefined, access: :undefined, atime: :undefined,
 mtime: :undefined, ctime: :undefined, mode: :undefined, links: :undefined,
 major_device: :undefined, minor_device: :undefined, inode: :undefined,
 uid: :undefined, gid: :undefined]

extract_all(opts)

Извлекает всю информацию о записях из файла Erlang.

Возвращает список ключевых слов кортежей {record_name, fields}, где record_name — имя извлеченной записи, а fields — список кортежей {field, value} полей для этой записи.

Параметры

Эта функция принимает следующие параметры, которые являются взаимоисключающими (т.е., только один из них может быть использован в одном вызове):

  • :from — (двоичное представление пути к файлу) путь к файлу Erlang, содержащий определения записей для извлечения; с этим параметром функция использует тот же поиск путей, что и атрибут -include в модулях Erlang.
  • :from_lib — (двоичное представление пути к файлу) путь к файлу Erlang, содержащий определения записей для извлечения; с этим параметром функция использует тот же поиск путей, что и атрибут -include_lib в модулях Erlang.

Ожидается, что эти параметры будут литералами (включая двоичные значения) во время компиляции.

is_record(data) (макрос)

Проверяет, является ли данная data записью.

Это реализовано как макрос, так как он может использоваться в условиях охраны.

Примеры

iex> record = {User, "john", 27}
iex> Record.is_record(record)
true
iex> tuple = {}
iex> Record.is_record(tuple)
false

is_record(data, kind) (макрос)

Проверяет, является ли данная data записью типа kind.

Это реализовано как макрос, так как он может использоваться в условиях охраны.

Примеры

iex> record = {User, "john", 27}
iex> Record.is_record(record, User)
true

© 2012 Plataformatec
Licensed under the Apache License, Version 2.0.
https://hexdocs.pm/elixir/1.4.5/Record.html

Spec-Zone.ru

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