Вычисление
Чаще всего формы вычисляются автоматически в силу того, что они встречаются в выполняемой программе. В редких случаях может понадобиться написать код, который вычисляет форму, создаваемую во время выполнения, например после чтения формы из редактируемого текста или получения её из списка свойств. В таких случаях используйте функцию eval. Часто eval не нужна, и вместо неё следует использовать что-то другое. Например, чтобы получить значение переменной, хотя eval работает, предпочтительнее использовать symbol-value; а вместо хранения в списке свойств выражений, которые затем нужно передавать в eval, лучше хранить функции, которые затем передаются в funcall.
Функции и переменные, описанные в этом разделе, вычисляют формы, задают ограничения процесса вычисления или сохраняют недавно возвращённые значения. Загрузка файла также выполняет вычисление (см. Загрузка).
Как правило, чище и гибче хранить функцию в структуре данных и вызывать её с помощью funcall или apply, чем хранить в структуре данных выражение и вычислять его. Использование функций позволяет передавать им информацию в виде аргументов.
- Функция: eval form &optional lexical
-
Это основная функция для вычисления выражения. Она вычисляет form в текущем окружении и возвращает результат. Тип объекта form определяет способ его вычисления. См. раздел Виды форм.
Аргумент lexical задаёт правило видимости локальных переменных (см. раздел Правила видимости привязок переменных). Если он равен
t, это означает, что form следует вычислять с лексической видимостью; это рекомендуемое значение. Если аргумент опущен или равенnil, используется старое правило видимости переменных, основанное только на динамической видимости.Значением lexical также может быть непустой список, задающий определённое лексическое окружение для лексических привязок; однако эта возможность полезна только для специальных целей, например в отладчиках Emacs Lisp. Каждый элемент списка — это либо конс-ячейка, представляющая пару «лексический символ — значение», либо символ, представляющий (специальную) переменную, для которой при связывании используется динамическая видимость.
Поскольку
evalявляется функцией, выражение аргумента, указанное в вызовеeval, вычисляется дважды: один раз при подготовке перед вызовомevalи ещё раз самой функциейeval. Вот пример:(setq foo 'bar) ⇒ bar(setq bar 'baz) ⇒ baz ;; Hereevalreceives argumentfoo(eval 'foo) ⇒ bar ;; Hereevalreceives argumentbar, which is the value offoo(eval foo) ⇒ bazКоличество одновременно активных вызовов
evalограничено значениемmax-lisp-eval-depth(см. ниже).
- Команда: eval-region start end &optional stream read-function
-
Эта функция вычисляет формы в текущем буфере в области, заданной позициями start и end. Она считывает формы из области и вызывает для них
eval, пока не достигнет конца области или пока не возникнет необработанная ошибка.По умолчанию
eval-regionне выводит никаких данных. Однако, если stream не равенnil, все данные, выводимые функциями вывода (см. раздел Функции вывода), а также значения, полученные в результате вычисления выражений в области, печатаются с использованием stream. См. раздел Потоки вывода.Если read-function не равен
nil, он должен быть функцией, которая используется вместоreadдля последовательного чтения выражений. Эта функция вызывается с одним аргументом — потоком для чтения ввода. Для указания этой функции также можно использовать переменнуюload-read-function(см. раздел Как программы выполняют загрузку), но использование аргумента read-function надёжнее.eval-regionне перемещает точку. Она всегда возвращаетnil.
- Команда: eval-buffer &optional buffer-or-name stream filename unibyte print
Эта функция похожа на
eval-region, но её аргументы предоставляют другие необязательные возможности.eval-bufferработает со всей доступной частью буфера buffer-or-name (см. раздел Сужение области видимости в Руководстве GNU Emacs). buffer-or-name может быть буфером, именем буфера (строкой) илиnil(либо быть опущен), что означает использование текущего буфера. stream используется так же, как вeval-region, если только stream не равенnil, а print —nil. В этом случае значения, полученные в результате вычисления выражений, по-прежнему отбрасываются, но вывод функций вывода печатается в области эха. filename — это имя файла, используемое дляload-history(см. раздел Выгрузка); по умолчанию оно равноbuffer-file-name(см. раздел Имя файла буфера). Если unibyte не равенnil,readпо возможности преобразует строки в однобайтные.
- Пользовательский параметр: max-lisp-eval-depth
-
Эта переменная задаёт максимальную глубину вызовов
eval,applyиfuncall, после превышения которой возникает ошибка (с сообщением"Lisp nesting exceeds max-lisp-eval-depth").Это ограничение и связанная с его превышением ошибка позволяют Emacs Lisp избегать бесконечной рекурсии в некорректно определённой функции. Если слишком сильно увеличить значение
max-lisp-eval-depth, такой код вместо этого может вызвать переполнение стека. В некоторых системах это переполнение можно обработать. В таком случае обычное вычисление Lisp прерывается, а управление передаётся обратно в главный цикл команд верхнего уровня (top-level). Обратите внимание, что в этой ситуации войти в отладчик Emacs Lisp невозможно. См. раздел Вызов отладчика при ошибке.Ограничение глубины учитывает внутреннее использование
eval,applyиfuncall, например при вызове функций, упомянутых в выражениях Lisp, при рекурсивном вычислении аргументов вызова функции и форм её тела, а также при явных вызовах в коде Lisp.Значение этой переменной по умолчанию — 1600. Если задать значение меньше 100, Lisp сбросит его до 100 при достижении заданного значения.
- Пользовательский параметр: lisp-eval-depth-reserve
-
Чтобы иметь возможность отлаживать ошибки бесконечной рекурсии, при вызове отладчика Lisp Emacs временно увеличивает значение
max-lisp-eval-depth, если оставшегося запаса глубины мало, чтобы у самого отладчика было достаточно ресурсов для работы. То же происходит при запуске обработчикаhandler-bind. См. раздел Написание кода для обработки ошибок.Переменная
lisp-eval-depth-reserveограничивает дополнительную глубину, которую Emacs может добавить кmax-lisp-eval-depthв таких исключительных случаях.Значение этой переменной по умолчанию — 200.
- Переменная: values
-
Значение этой переменной — список значений, возвращённых всеми выражениями, которые были считаны, вычислены и выведены из буферов (включая минибуфер) стандартными командами Emacs, выполняющими эти действия. (Обратите внимание, что сюда не входит вычисление в буферах *ielm* и вычисление с помощью C-j, C-x C-e и подобных команд в
lisp-interaction-mode.)Эта переменная устарела и будет удалена в будущей версии, поскольку постоянно увеличивает объём памяти, используемой процессом Emacs. Поэтому мы не рекомендуем её использовать.
Элементы
valuesупорядочены от самых новых к самым старым.(setq x 1) ⇒ 1(list 'A (1+ 2) auto-save-default) ⇒ (A 3 t)values ⇒ ((A 3 t) 1 ...)Эта переменная может пригодиться для обращения к значениям недавно вычисленных форм. Обычно не следует выводить само значение
values, поскольку оно может быть очень длинным. Вместо этого изучайте отдельные элементы, например так:;; Refer to the most recent evaluation result. (nth 0 values) ⇒ (A 3 t);; That put a new element on, ;; so all elements move back one. (nth 1 values) ⇒ (A 3 t)
;; This gets the element that was next-to-most-recent ;; before this example. (nth 3 values) ⇒ 1
Copyright © 1990-1996, 1998-2026 Free Software Foundation, Inc.
Licensed under the GNU GPL license.
https://www.gnu.org/software/emacs/manual/html_node/elisp/Eval.html