Jisang Yoo
Jisang Yoo

Reputation: 3745

whether and how to avoid eval in defadvice loop

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))))

Upvotes: 1

Views: 126

Answers (1)

Stefan
Stefan

Reputation: 28531

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))

Upvotes: 3

Related Questions