Оценивание
Чаще всего формы оцениваются автоматически в силу их появления в выполняемой программе. В редких случаях вам может потребоваться написать код, который оценивает форму, вычисленную во время выполнения, например, после чтения формы из редактируемого текста или получения её из списка свойств. В таких случаях используйте функцию eval. Часто eval не требуется, и следует использовать что-то другое. Например, чтобы получить значение переменной, хотя eval работает, symbol-value предпочтительнее; или вместо хранения выражений в списке свойств, которые затем должны пройти через eval, лучше хранить функции, которые затем передаются в funcall.
Функции и переменные, описанные в этом разделе, оценивают формы, задают ограничения для процесса оценивания или записывают недавно возвращённые значения. Загрузка файла также выполняет оценивание (см. Загрузка).
В целом, более чисто и гибко хранить функцию в структуре данных и вызывать её с помощью funcall или apply, чем хранить выражение в структуре данных и вычислять его. Использование функций позволяет передавать им информацию в качестве аргументов.
- Функция: eval form &optional lexical
-
Это основная функция для оценивания выражения. Она оценивает form в текущей среде и возвращает результат. Тип объекта form определяет, как он оценивается. См. Формы.
Аргумент lexical определяет правило области действия для локальных переменных (см. Области действия переменных). Если он опущен или
nil, это означает, что form оценивается с использованием правила динамической области действия по умолчанию. Если онt, это означает, что используется правило лексической области действия. Значение 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преобразует строки в однобайтовые, когда это возможно.eval-current-bufferявляется псевдонимом для этой команды.
- Пользовательская опция: 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.Значение этой переменной по умолчанию составляет 800. Если вы установите его значение меньше 100, Lisp восстановит его до 100, если указанное значение будет достигнуто. Вход в отладчик Lisp увеличивает значение, если места осталось мало, чтобы убедиться, что у самого отладчика достаточно места для выполнения.
max-specpdl-sizeобеспечивает другое ограничение на вложенность. См. Локальные переменные.
- Переменная: 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-2022 Free Software Foundation, Inc.
Licensed under the GNU GPL license.
https://www.gnu.org/software/emacs/manual/html_node/elisp/Eval.html