Emacs lisp: передать лексическую область видимости функции?
Python 3 имеет функцию locals()
анс globals()
которые позволяют передавать именованные значения текущей области как минимум для целей только для чтения в функцию.
В emacs lisp я хочу написать функцию для интерполяции строк. Для этого потребуется доступ к лексическим переменным области вызова. Поскольку я хочу избежать перекомпиляции других файлов при изменении макроса, очевидное решение - использование макроса - нежизнеспособно.
Есть ли возможность сделать это в emacs lisp?
Я уже попробовал функцию lisp--local-variables
но это не работает с lexical-binding
являющийся t
,
Некоторые соответствующие цитаты из документации Elisp
(Внутренне, лексическое окружение - это список пар символ-значение, причем конечным элементом в списке является символ `t ', а не cons-ячейка. Такой список может быть передан в качестве второго аргумента функции` eval', чтобы указать лексическую среду для оценки формы. * Обратите внимание на Eval::. Однако большинство программ на Emacs Lisp не должны напрямую взаимодействовать с лексической средой, а только специализированные программы, такие как отладчики.)
В настоящее время объект замыкания Emacs Lisp представлен списком с символом "замыкание" в качестве первого элемента, списком, представляющим лексическое окружение в качестве второго элемента, а списком аргументов и телом являются оставшиеся элементы:
;; lexical binding is enabled. (lambda (x) (* x x)) => (closure (t) (x) (* x x))
Однако тот факт, что внутренняя структура замыкания "выставлена" остальному миру Lisp, считается внутренней деталью реализации. По этой причине мы не рекомендуем непосредственно проверять или изменять структуру замыкающих объектов.
1 ответ
Если бы я сделал это, я бы не сделал функцию интерполяции строк, я бы создал макрос интерполяции строк, который возвращает подходящий фрагмент кода для вычисления интерполированной строки в правильной лексической среде.
Это, в конце концов, одно из действительно удобных применений для макросов.
Если вы пишете и отлаживаете макрос в "изоляции" (до того, как вы интенсивно используете его в другом коде), ваш страх перед необходимостью перекомпиляции должен быть главным образом страхом. После отладки вам не нужно менять макрос для существующей функциональности, и если вам нужно добавить новую функциональность, это не то, что уже использовалось (однако, в любом случае, вероятно, неплохо бы перекомпилировать код время от времени),