Spec-Zone.ru › Elisp

Оценивание

Чаще всего формы оцениваются автоматически в силу их появления в выполняемой программе. В редких случаях вам может потребоваться написать код, который оценивает форму, вычисленную во время выполнения, например, после чтения формы из редактируемого текста или получения её из списка свойств. В таких случаях используйте функцию 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
;; Here eval receives argument foo
(eval 'foo)
     ⇒ bar
;; Here eval receives argument bar, which is the value of foo
(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

Spec-Zone.ru

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