Spec-Zone.ru › Elixir 1.18

Источник Macro.Env

Структура, хранящая информацию об окружении во время компиляции.

Текущее окружение можно получить в любой момент как __ENV__/0. Внутри макросов, окружение вызывающего макрос можно получить как __CALLER__/0.

Большинство функций в этом модуле предназначены для инструментов низкого уровня, которым необходимо взаимодействовать с компилятором Elixir, таких как серверы языка и встроенные языки. Для обычного использования в коде Elixir и макросах необходимо использовать модуль Macro вместо этого. В частности, избегайте непосредственного изменения структуры Macro.Env и предпочитайте использовать высокоуровневые конструкции, такие как import, aliases, и т. д., для построения собственного окружения. Например, для построения пользовательского окружения можно определить функцию, такую как:

def make_custom_env do
  import SomeModule, only: [some_function: 2], warn: false
  alias A.B.C, warn: false
  __ENV__
end

Поля структуры

Структура Macro.Env содержит следующие поля:

  • context - контекст окружения; он может быть nil (по умолчанию), :guard (внутри условия) или :match (внутри совпадения)
  • context_modules - список модулей, определённых в текущем контексте
  • file - текущее абсолютное имя файла в виде бинарного значения
  • function - кортеж как {atom, integer}, где первый элемент - имя функции, а второй - её арность; возвращает nil если не находится внутри функции
  • line - текущая строка в виде целого числа
  • module - текущее имя модуля

Следующие поля предназначены для механизма макрорасширения Elixir и не должны использоваться напрямую:

  • aliases
  • functions
  • macro_aliases
  • macros
  • lexical_tracker
  • requires
  • tracers
  • versioned_vars

Резюме

Типы

context()
context_modules()
file()
line()
name_arity()
t()
variable()

Функции

define_alias(env, meta, module, opts \\ [])

Определяет заданный as как псевдоним для module в окружении.

define_import(env, meta, module, opts \\ [])

Определяет заданный module как импорт в окружении.

define_require(env, meta, module, opts \\ [])

Определяет заданный module как require в окружении.

expand_alias(env, meta, list, opts \\ [])

Расширяет псевдоним, заданный сегментами псевдонима.

expand_import(env, meta, name, arity, opts \\ [])

Расширяет импорт, заданный name и arity.

expand_require(env, meta, module, name, arity, opts \\ [])

Расширяет require, заданный module, name, и arity.

has_var?(env, var)

Проверяет, принадлежит ли переменная окружению.

in_guard?(env)

Возвращает значение true, если окружение компиляции находится внутри условия.

in_match?(env)

Возвращает значение true, если окружение компиляции находится внутри блока совпадения.

location(env)

Возвращает список ключевых слов, содержащий информацию о файле и строке в качестве ключей.

lookup_alias_as(env, atom)

Возвращает имена любых псевдонимов для данного модуля или атома.

lookup_import(env, name_arity)

Возвращает модули, из которых был импортирован данный {name, arity}.

prepend_tracer(env, tracer)

Добавляет отслеживатель в начало списка отслеживателей в окружении.

prune_compile_info(env)

Удаляет информацию о компиляции из окружения.

required?(env, module)

Возвращает true если указанный модуль был загружен.

stacktrace(env)

Возвращает стек вызовов окружения.

to_guard(env)

Возвращает окружение в контексте условия.

to_match(env)

Возвращает окружение в контексте совпадения.

vars(env)

Возвращает список переменных в текущем окружении.

Типы

context()Источник

@type context() :: :match | :guard | nil

context_modules()Источник

@type context_modules() :: [module()]

file()Источник

@type file() :: binary()

line()Источник

@type line() :: non_neg_integer()

name_arity()Источник

@type name_arity() :: {atom(), arity()}

t()Источник

@type t() :: %Macro.Env{
  aliases: aliases(),
  context: context(),
  context_modules: context_modules(),
  file: file(),
  function: name_arity() | nil,
  functions: functions(),
  lexical_tracker: lexical_tracker(),
  line: line(),
  macro_aliases: macro_aliases(),
  macros: macros(),
  module: module(),
  requires: requires(),
  tracers: tracers(),
  versioned_vars: versioned_vars()
}

variable()Источник

@type variable() :: {atom(), atom() | term()}

Функции

define_alias(env, meta, module, opts \\ [])Source

@spec define_alias(t(), Macro.metadata(), module(), keyword()) ::
  {:ok, t()} | {:error, String.t()}

Определяет заданный as как псевдоним для module в среде.

Используется инструментами, которые нуждаются в имитации компилятора Elixir. Будет выброшено соответствующее событие отслеживания компилятора :alias.

Дополнительные параметры

Принимает те же параметры, что и Kernel.SpecialForm.alias/2, плюс:

  • :trace - при установке в false, отключает отслеживание компиляции и отслеживание лексических единиц. Этот параметр должен использоваться только серверами языков программирования и другими инструментами, которым необходимо инспектировать код без влияния на его компиляцию. Отключение отслеживания внутри макросов или обычного расширения кода крайне не рекомендуется, так как это блокирует компилятор от точного отслеживания зависимостей.

Примеры

iex> env = __ENV__
iex> Macro.Env.expand_alias(env, [], [:Baz])
:error
iex> {:ok, env} = Macro.Env.define_alias(env, [line: 10], Foo.Bar, as: Baz)
iex> Macro.Env.expand_alias(env, [], [:Baz])
{:alias, Foo.Bar}
iex> Macro.Env.expand_alias(env, [], [:Baz, :Bat])
{:alias, Foo.Bar.Bat}

Если параметр :as не задан, псевдоним будет выведен из модуля:

iex> env = __ENV__
iex> {:ok, env} = Macro.Env.define_alias(env, [line: 10], Foo.Bar)
iex> Macro.Env.expand_alias(env, [], [:Bar])
{:alias, Foo.Bar}

Если это невозможно определить, возвращается ошибка:

iex> Macro.Env.define_alias(__ENV__, [line: 10], :an_atom)
{:error,
 "alias cannot be inferred automatically for module: :an_atom, " <>
   "please use the :as option. Implicit aliasing is only supported with Elixir modules"}

define_import(env, meta, module, opts \\ [])Source

@spec define_import(t(), Macro.metadata(), module(), keyword()) ::
  {:ok, t()} | {:error, String.t()}

Определяет заданный module как импортированный в среде.

Предполагает, что module доступен. Используется инструментами, которые нуждаются в имитации компилятора Elixir. Будет выброшено соответствующее событие отслеживания компилятора :import.

Дополнительные параметры

Принимает те же параметры, что и Kernel.SpecialForm.import/2, плюс:

  • :emit_warnings - генерировать предупреждения, найденные при определении импортов

  • :trace - при установке в false, отключает отслеживание компиляции и отслеживание лексических единиц. Этот параметр должен использоваться только серверами языков программирования и другими инструментами, которым необходимо инспектировать код без влияния на его компиляцию. Отключение отслеживания внутри макросов или обычного расширения кода крайне не рекомендуется, так как это блокирует компилятор от точного отслеживания зависимостей

  • :info_callback - функция, используемая вместо Module.__info__/1. Функция будет вызвана с аргументом :functions или :macros. Она должна возвращать список пар ключ-значение {function, arity}. В случае ошибки используется метаданные модуля, основанные на module_info/1.

Примеры

iex> env = __ENV__
iex> Macro.Env.lookup_import(env, {:flatten, 1})
[]
iex> {:ok, env} = Macro.Env.define_import(env, [line: 10], List)
iex> Macro.Env.lookup_import(env, {:flatten, 1})
[{:function, List}]

Принимает те же параметры, что и Kernel.SpecialForm.import/2:

iex> env = __ENV__
iex> Macro.Env.lookup_import(env, {:is_odd, 1})
[]
iex> {:ok, env} = Macro.Env.define_import(env, [line: 10], Integer, only: :macros)
iex> Macro.Env.lookup_import(env, {:is_odd, 1})
[{:macro, Integer}]

Переопределение обратного вызова info

iex> env = __ENV__
iex> Macro.Env.lookup_import(env, {:flatten, 1})
[]
iex> {:ok, env} = Macro.Env.define_import(env, [line: 10], SomeModule, [info_callback: fn :functions -> [{:flatten, 1}]; :macros -> [{:some, 2}]; end])
iex> Macro.Env.lookup_import(env, {:flatten, 1})
[{:function, SomeModule}]
iex> Macro.Env.lookup_import(env, {:some, 2})
[{:macro, SomeModule}]

define_require(env, meta, module, opts \\ [])Source

Определяет заданный module как требуемый в среде.

Не проверяет и не утверждает, что модуль доступен. Используется инструментами, которые нуждаются в имитации компилятора Elixir. Будет выброшено соответствующее событие отслеживания компилятора :require.

Дополнительные параметры

Принимает те же параметры, что и Kernel.SpecialForm.require/2, плюс:

  • :trace - при установке в false, отключает отслеживание компиляции и отслеживание лексических единиц. Этот параметр должен использоваться только серверами языков программирования и другими инструментами, которым необходимо инспектировать код без влияния на его компиляцию. Отключение отслеживания внутри макросов или обычного расширения кода крайне не рекомендуется, так как это блокирует компилятор от точного отслеживания зависимостей

Примеры

iex> env = __ENV__
iex> Macro.Env.required?(env, Integer)
false
iex> {:ok, env} = Macro.Env.define_require(env, [line: 10], Integer)
iex> Macro.Env.required?(env, Integer)
true

Если задан параметр :as, будет также определен псевдоним:

iex> env = __ENV__
iex> {:ok, env} = Macro.Env.define_require(env, [line: 10], Foo.Bar, as: Baz)
iex> Macro.Env.expand_alias(env, [], [:Baz])
{:alias, Foo.Bar}

expand_alias(env, meta, list, opts \\ [])Source

@spec expand_alias(t(), keyword(), [atom()], keyword()) :: {:alias, atom()} | :error

Расширяет псевдоним, заданный сегментами псевдонима.

Возвращает {:alias, alias} если сегменты — список атомов и псевдоним был найден. В противном случае возвращает :error.

Это расширение может генерировать событие отслеживания :alias_expansion, но не :alias_reference.

Параметры

  • :trace - при установке в false, отключает отслеживание компиляции и отслеживание лексических единиц. Этот параметр должен использоваться только серверами языков программирования и другими инструментами, которым необходимо инспектировать код без влияния на его компиляцию. Отключение отслеживания внутри макросов или обычного расширения кода крайне не рекомендуется, так как это блокирует компилятор от точного отслеживания зависимостей

Примеры

iex> alias List, as: MyList
iex> Macro.Env.expand_alias(__ENV__, [], [:MyList])
{:alias, List}
iex> Macro.Env.expand_alias(__ENV__, [], [:MyList, :Nested])
{:alias, List.Nested}

Если псевдонима нет или псевдоним начинается с Elixir. (что отключает алиасинг), возвращается :error:

iex> alias List, as: MyList
iex> Macro.Env.expand_alias(__ENV__, [], [:Elixir, MyList])
:error
iex> Macro.Env.expand_alias(__ENV__, [], [:AnotherList])
:error

expand_import(env, meta, name, arity, opts \\ [])Source

@spec expand_import(t(), keyword(), atom(), arity(), keyword()) ::
  {:macro, module(), (Macro.metadata(), args :: [Macro.t()] -> Macro.t())}
  | {:function, module(), atom()}
  | {:error, :not_found | {:conflict, module()} | {:ambiguous, [module()]}}

Расширяет импорт, заданный name и arity.

Если импорт указывает на макрос, возвращает кортеж с модулем и функцией, расширяющей макрос. Функция ожидает, что метаданные будут прикреплены к расширению и аргументы макроса.

Если импорт указывает на функцию, возвращает кортеж с модулем и именем функции.

Если найден какой-либо импорт, будет выброшено соответствующее событие отслеживания компилятора.

В противном случае возвращает {:error, reason}.

Параметры

  • :allow_locals - при установке в false, не пытается захватить локальные макросы, определенные в текущем модуле в env

  • :check_deprecations - при установке в false, не проверяет устаревшие функции при расширении макросов

  • :trace - при установке в false, отключает отслеживание компиляции и отслеживание лексических единиц. Этот параметр должен использоваться только серверами языков программирования и другими инструментами, которым необходимо инспектировать код без влияния на его компиляцию. Отключение отслеживания внутри макросов или обычного расширения кода крайне не рекомендуется, так как это блокирует компилятор от точного отслеживания зависимостей

expand_require(env, meta, module, name, arity, opts \\ [])Source

@spec expand_require(t(), keyword(), module(), atom(), arity(), keyword()) ::
  {:macro, module(), (Macro.metadata(), args :: [Macro.t()] -> Macro.t())}
  | :error

Расширяет require, заданный module, name, и arity.

Если require указывает на макрос, и модуль был загружен, возвращает кортеж с модулем и функцией, расширяющей макрос. Функция ожидает, что метаданные будут прикреплены к расширению и аргументы макроса. Соответствующее событие отслеживания компилятора :remote_macro будет выброшено, если найден макрос (обратите внимание, что событие :remote_function не генерируется в случаях :error).

В противном случае возвращает :error.

Параметры

  • :check_deprecations - при установке в false, не проверяет устаревшие функции при расширении макросов

  • :trace - при установке в false, отключает отслеживание компиляции и отслеживание лексических единиц. Этот параметр должен использоваться только серверами языков программирования и другими инструментами, которым необходимо инспектировать код без влияния на его компиляцию. Отключение отслеживания внутри макросов или обычного расширения кода крайне не рекомендуется, так как это блокирует компилятор от точного отслеживания зависимостей

has_var?(env, var)Source

@spec has_var?(t(), variable()) :: boolean()

Проверяет, принадлежит ли переменная среде.

Примеры

iex> x = 13
iex> x
13
iex> Macro.Env.has_var?(__ENV__, {:x, nil})
true
iex> Macro.Env.has_var?(__ENV__, {:unknown, nil})
false

in_guard?(env)Source

@spec in_guard?(t()) :: boolean()

Возвращает значение, указывающее, находится ли среда компиляции в данный момент внутри условия.

in_match?(env)Source

@spec in_match?(t()) :: boolean()

Возвращает значение, указывающее, находится ли среда компиляции в данный момент внутри условия соответствия.

location(env)Source

@spec location(t()) :: keyword()

Возвращает список ключевых слов, содержащих информацию о файле и строке в качестве ключей.

lookup_alias_as(env, atom)Source

@spec lookup_alias_as(t(), atom()) :: [atom()]

Возвращает имена любых псевдонимов для данного модуля или атома.

Примеры

iex> alias Foo.Bar
iex> Bar
Foo.Bar
iex> Macro.Env.lookup_alias_as(__ENV__, Foo.Bar)
[Elixir.Bar]
iex> alias Foo.Bar, as: Baz
iex> Baz
Foo.Bar
iex> Macro.Env.lookup_alias_as(__ENV__, Foo.Bar)
[Elixir.Bar, Elixir.Baz]
iex> Macro.Env.lookup_alias_as(__ENV__, Unknown)
[]

lookup_import(env, name_arity)Source

@spec lookup_import(t(), name_arity()) :: [{:function | :macro, module()}]

Возвращает модули, из которых был импортирован данный {name, arity}.

Возвращает список кортежей из двух элементов в форме {:function | :macro, module}. Элементы в списке расположены в произвольном порядке, и порядок не гарантируется.

Использовать только для интроспекции

Эта функция не генерирует события отслеживания компилятора, что может помешать компилятору правильно отслеживать зависимости. Используйте эту функцию для целей рефлексии, но не используйте её для расширения импортов в квалифицированные вызовы. Вместо этого используйте expand_import/5.

Примеры

iex> Macro.Env.lookup_import(__ENV__, {:duplicate, 2})
[]
iex> import Tuple, only: [duplicate: 2], warn: false
iex> Macro.Env.lookup_import(__ENV__, {:duplicate, 2})
[{:function, Tuple}]
iex> import List, only: [duplicate: 2], warn: false
iex> Macro.Env.lookup_import(__ENV__, {:duplicate, 2})
[{:function, List}, {:function, Tuple}]

iex> Macro.Env.lookup_import(__ENV__, {:def, 1})
[{:macro, Kernel}]

prepend_tracer(env, tracer)Source

@spec prepend_tracer(t(), module()) :: t()

Добавляет отслеживатель в начало списка отслеживателей в среде.

Примеры

Macro.Env.prepend_tracer(__ENV__, MyCustomTracer)

prune_compile_info(env)Source

@spec prune_compile_info(t()) :: t()

Удаляет информацию о компиляции из среды.

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

required?(env, module)Source

@spec required?(t(), module()) :: boolean()

Возвращает true, если данный модуль был загружен.

Примеры

iex> Macro.Env.required?(__ENV__, Integer)
false
iex> require Integer
iex> Macro.Env.required?(__ENV__, Integer)
true

iex> Macro.Env.required?(__ENV__, Kernel)
true

stacktrace(env)Source

@spec stacktrace(t()) :: list()

Возвращает стек вызовов среды.

to_guard(env)Source

@spec to_guard(t()) :: t()

Возвращает среду в контексте условия.

to_match(env)Source

@spec to_match(t()) :: t()

Возвращает среду в контексте сопоставления.

vars(env)Source

@spec vars(t()) :: [variable()]

Возвращает список переменных в текущей среде.

Каждая переменная идентифицируется кортежем из двух элементов: имя переменной в виде атома и её контекст, который может быть атомом или целым числом.

Скачать версию ePub

Создано с помощью ExDoc (v0.36.1) для языка программирования Elixir

© 2012-2024 The Elixir Team
Licensed under the Apache License, Version 2.0.
https://hexdocs.pm/elixir/1.18.1/Macro.Env.html

Spec-Zone.ru

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