Spec-Zone.ru › Elixir 1.5

Запись

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

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

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 использует имя записи в качестве первого элемента кортежа («тега»). Однако можно указать другой тег при определении записи, как в следующем примере, в котором мы используем Customer в качестве второго аргумента defrecord/3:

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

require User
User.user() #=> {Customer, 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)

extract(name :: atom(), keyword()) :: keyword()

Извлекает информацию о записи из файла 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)

extract_all(keyword()) :: [{name :: atom(), keyword()}]

Извлекает всю информацию о записях из файла 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.5.3/Record.html

Spec-Zone.ru

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