mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-15 10:30:25 -08:00
Add cl-with-accessors
* lisp/emacs-lisp/cl-macs.el (cl-with-accessors): New macro. * doc/misc/cl.texi (Structures): Mention the new macro. * test/lisp/emacs-lisp/cl-macs-tests.el (cl-lib-struct-with-accessors): New Test. * etc/NEWS (New macro 'cl-with-accessors'.): Mention the macro. This macro is useful when making repeated use of a structures accessor functions, such as reading from a slot and then writing to a slot. It is similar to 'with-slots' from EIEIO, but uses accessor functions instead of slot names.
This commit is contained in:
parent
a97a61b630
commit
e04d1dafc7
4 changed files with 118 additions and 0 deletions
|
|
@ -2576,6 +2576,50 @@ See also `macroexp-let2'."
|
|||
collect `(,(car name) ,gensym))
|
||||
,@body)))))
|
||||
|
||||
;;;###autoload
|
||||
(defmacro cl-with-accessors (bindings instance &rest body)
|
||||
"Use BINDINGS as function calls on INSTANCE inside BODY.
|
||||
|
||||
This macro helps when writing code that makes repeated use of the
|
||||
accessor functions of a structure or object instance, such as those
|
||||
created by `cl-defstruct' and `defclass'.
|
||||
|
||||
BINDINGS is a list of (NAME ACCESSOR) pairs. Inside BODY, NAME is
|
||||
treated as the function call (ACCESSOR INSTANCE) using
|
||||
`cl-symbol-macrolet'. NAME can be used with `setf' and `setq' as a
|
||||
generalized variable. Because of how the accessor is used,
|
||||
`cl-with-accessors' can be used with any generalized variable that can
|
||||
take a single argument, such as `car' and `cdr'.
|
||||
|
||||
See also the macro `with-slots' described in the Info
|
||||
node `(eieio)Accessing Slots', which is similar, but uses slot names
|
||||
instead of accessor functions.
|
||||
|
||||
\(fn ((NAME ACCESSOR) ...) INSTANCE &rest BODY)"
|
||||
(declare (debug [(&rest (symbolp symbolp)) form body])
|
||||
(indent 2))
|
||||
(cond ((null body)
|
||||
(macroexp-warn-and-return "`cl-with-accessors' used with empty body"
|
||||
nil 'empty-body))
|
||||
((null bindings)
|
||||
(macroexp-warn-and-return "`cl-with-accessors' used without accessors"
|
||||
(macroexp-progn body)
|
||||
'suspicious))
|
||||
(t
|
||||
(cl-once-only (instance)
|
||||
(let ((symbol-macros))
|
||||
(dolist (b bindings)
|
||||
(pcase b
|
||||
(`(,(and (pred symbolp) var)
|
||||
,(and (pred symbolp) accessor))
|
||||
(push `(,var (,accessor ,instance))
|
||||
symbol-macros))
|
||||
(_
|
||||
(error "Malformed `cl-with-accessors' binding: %S" b))))
|
||||
`(cl-symbol-macrolet
|
||||
,symbol-macros
|
||||
,@body))))))
|
||||
|
||||
;;; Multiple values.
|
||||
|
||||
;;;###autoload
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue