whether and how to avoid eval in defadvice loop

125 Views Asked by At

Should one avoid eval in the following code? If so, how? Or is this one of exceptional cases where using eval is better?

(dolist (command '(....))
  (eval
   `(defadvice ,command (around blah activate)
      ...)))

For a real life example of the idiom above:

(dolist (command '(paredit-comment-dwim comment-dwim))
  (eval
   `(defadvice ,command (around my-check-parens-and-warn-for-comment activate)
      (if (and (called-interactively-p 'any)
               (use-region-p))
          (progn
            (my-check-parens-and-warn-if-mismatch "You commented out a region and introduced a mismatched paren")
            ad-do-it
            (my-check-parens-and-warn-if-mismatch "You uncommented out a region and introduced a mismatched paren"))
        ad-do-it))))
1

There are 1 best solutions below

1
Stefan On BEST ANSWER

Two solutions:

  • Use ad-add-advice instead of defadvice.
  • If you're using Emacs trunk, you can use the new advice-add.

Using advice-add would look like the following code:

(defun my-check-commented-parens (orig-fun &rest args)
  (if (not (and (called-interactively-p 'any)
                (use-region-p)))
      (apply orig-fun args)
    (my-check-parens-and-warn-if-mismatch "You commented out a region and introduced a mismatched paren")
    (apply orig-fun args)
    (my-check-parens-and-warn-if-mismatch "You uncommented out a region and introduced a mismatched paren")))

(dolist (command '(paredit-comment-dwim comment-dwim))
  (advice-add command :around #'my-check-commented-parens))