summaryrefslogtreecommitdiff
path: root/lisp/emacs-lisp
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/emacs-lisp')
-rw-r--r--lisp/emacs-lisp/cl-macs.el44
1 files changed, 44 insertions, 0 deletions
diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el
index 960f2e6742b..cc1c6a6a5ad 100644
--- a/lisp/emacs-lisp/cl-macs.el
+++ b/lisp/emacs-lisp/cl-macs.el
@@ -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