Spec-Zone.ru › Elixir 1.3

Запись

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

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

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

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

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

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

Макросы defrecord/3 и defrecordp/3 могут быть использованы для создания записей, а extract/2 может быть использован для извлечения записей из файлов 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, тег (который по умолчанию) — имя, если не указано, и набор полей, заданный kv.

Примеры

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

В примере выше будет определен набор макросов с именем 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}

# 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.

Возвращает выражение с цитированием, содержащее поля в виде списка кортежей. Ожидает, что имя записи будет атомом, а путь к библиотеке — строкой во время расширения.

Примеры

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.

Возвращает список ключевых слов, содержащий имена извлеченных записей в качестве ключей и списки кортежей, описывающих поля, в качестве значений. Ожидает именованный аргумент :from или :from_lib, которые соответствуют атрибутам include или 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.3.4/Record.html

Spec-Zone.ru

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