Spec-Zone.ru › Elisp

Определение новых форм setf

В этом разделе описывается, как определять новые формы, с которыми может работать setf.

Макрос: gv-define-simple-setter name setter &optional fix-return

Этот макрос позволяет легко определять методы setf для простых случаев. name — это имя функции, макроса или специальной формы. Этот макрос можно использовать, когда name имеет непосредственно соответствующую функцию setter, которая обновляет его, например, (gv-define-simple-setter car setcar).

Этот макрос преобразует вызов следующей формы

(setf (name args...) value)

в

(setter args... value)

Документировано, что такой вызов setf возвращает value. Это не проблема, например, для car и setcar, поскольку setcar возвращает установленное им значение. Если ваша функция setter не возвращает value, передайте аргументу fix-return макроса gv-define-simple-setter значение, отличное от nil. В результате раскрывается форма, эквивалентная следующей:

(let ((temp value))
  (setter args... temp)
  temp)

что гарантирует возврат правильного результата.

Макрос: gv-define-setter name arglist &rest body

Этот макрос позволяет создавать более сложные раскрытия setf, чем предыдущая форма. Например, может потребоваться использовать эту форму, если нет простой функции установки, которую можно вызвать, или если такая функция есть, но для неё нужны аргументы, отличающиеся от аргументов формы места.

Этот макрос раскрывает форму (setf (name args…) value): сначала связывает формы аргументов setf (value args…) согласно arglist, а затем выполняет body. body должен возвращать форму Lisp, выполняющую присваивание и в конце возвращающую установленное значение. Пример использования этого макроса:

(gv-define-setter caar (val x) `(setcar (car ,x) ,val))
Макрос: gv-define-expander name handler

Для более точного управления раскрытием можно использовать макрос gv-define-expander. Например, присваиваемое значение substring можно реализовать следующим образом:

(gv-define-expander substring
  (lambda (do place from &optional to)
    (gv-letplace (getter setter) place
      (macroexp-let2* (from to)
        (funcall do `(substring ,getter ,from ,to)
                 (lambda (v)
                   (macroexp-let2* (v)
                     `(progn
                        ,(funcall setter `(cl--set-substring
                                           ,getter ,from ,to ,v))
                        ,v))))))))
Макрос: gv-letplace (getter setter) place &rest body

Макрос gv-letplace может быть полезен при определении макросов, работающих подобно setf; например, макрос incf из Common Lisp можно реализовать следующим образом:

(defmacro incf (place &optional n)
  (gv-letplace (getter setter) place
    (macroexp-let2* ((v (or n 1)))
      (funcall setter `(+ ,v ,getter)))))

getter будет связан с копируемым выражением, возвращающим значение place. setter будет связан с функцией, принимающей выражение v и возвращающей новое выражение, которое присваивает place значение v. body должен возвращать выражение Emacs Lisp, которое манипулирует place с помощью getter и setter.

Дополнительные сведения см. в исходном файле gv.el.

Функция: make-obsolete-generalized-variable obsolete-name current-name when

Эта функция указывает байт-компилятору выдавать предупреждение об устаревании обобщённой переменной obsolete-name. Если current-name — символ, текст предупреждения предписывает использовать current-name вместо obsolete-name. Если current-name — строка, она используется как текст предупреждения. when должен быть строкой, указывающей, когда переменная впервые была объявлена устаревшей (обычно это строка с номером версии).

Примечание о Common Lisp: Common Lisp определяет другой способ указания поведения setf функции, а именно функции setf, имена которых представляют собой списки (setf name), а не символы. Например, (defun (setf foo) …) определяет функцию, используемую при применении setf к foo. Emacs этого не поддерживает. Использование setf для формы, для которой ещё не определено соответствующее раскрытие, приводит к ошибке времени компиляции. В Common Lisp это не является ошибкой, поскольку функция (setf func) может быть определена позднее.

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/Adding-Generalized-Variables.html

Spec-Zone.ru

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