Spec-Zone.ru › Elisp

Перенаправление функции символа

Если первый элемент списка является символом, при вычислении проверяется ячейка функции этого символа, и вместо исходного символа используется её содержимое. Если содержимое является другим символом, этот процесс, называемый перенаправлением функции символа, повторяется, пока не будет получен объект, не являющийся символом. Дополнительные сведения о перенаправлении функции символа см. в разделе Именование функции. В итоге мы получаем объект, не являющийся символом, который должен быть функцией или другим подходящим объектом.

Точнее, теперь мы должны получить функцию Lisp (лямбда-выражение), функцию в байт-коде, примитивную функцию, макрос Lisp, специальную форму или объект автозагрузки. Каждый из этих типов рассматривается в одном из следующих разделов. Если объект не относится ни к одному из этих типов, Emacs сигнализирует об ошибке invalid-function.

Следующий пример иллюстрирует процесс перенаправления символа. Мы используем fset, чтобы установить ячейку функции символа, и symbol-function, чтобы получить содержимое ячейки функции (см. раздел Доступ к содержимому ячейки функции). В частности, мы сохраняем символ car в ячейке функции символа first, а символ first — в ячейке функции символа erste.

;; Build this function cell linkage:
;;   -------------       -----        -------        -------
;;  | #<subr car> | <-- | car |  <-- | first |  <-- | erste |
;;   -------------       -----        -------        -------
(symbol-function 'car)
     ⇒ #<subr car>
(fset 'first 'car)
     ⇒ car
(fset 'erste 'first)
     ⇒ first
(erste '(1 2 3))   ; Call the function referenced by erste.
     ⇒ 1

В отличие от этого, следующий пример вызывает функцию без перенаправления функции символа, поскольку первый элемент — это анонимная функция Lisp, а не символ.

((lambda (arg) (erste arg))
 '(1 2 3))
     ⇒ 1

Выполнение самой функции вычисляет её тело; при вызове erste перенаправление функции символа всё же происходит.

Эта форма используется редко и теперь считается устаревшей. Вместо неё следует написать:

(funcall (lambda (arg) (erste arg))
         '(1 2 3))

или просто

(let ((arg '(1 2 3))) (erste arg))

Встроенная функция indirect-function позволяет легко выполнять перенаправление функции символа явно.

Функция: indirect-function function

Эта функция возвращает значение function в качестве функции. Если function является символом, она находит определение функции для function и начинает выполнение заново с этим значением. Если function не является символом, функция возвращает сам function.

Эта функция возвращает nil, если последний символ не связан.

Также имеется второй необязательный аргумент, который устарел и не оказывает никакого влияния.

Вот как можно определить indirect-function на Lisp:

(defun indirect-function (function)
  (if (and function
           (symbolp function))
      (indirect-function (symbol-function function))
    function))

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/Function-Indirection.html

Spec-Zone.ru

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