Path: utzoo!attcan!uunet!cs.utexas.edu!rutgers!rochester!quiroz From: quiroz@cs.rochester.edu (Cesar Quiroz) Newsgroups: comp.emacs Subject: save-match-data Summary: dangerous as function, macro provided here Message-ID: <1989May16.115319.14490@cs.rochester.edu> Date: 16 May 89 15:53:19 GMT Reply-To: quiroz@cs.rochester.edu (Cesar Quiroz) Organization: U of Rochester, Dept. of Computer Science, Rochester, NY 14627 Lines: 49 In , David Lawrence proposed encapsulating the protection of global match data by using a function (defun save-match-data (&rest forms) ...). As functions evaluate their arguments first, this approach requires you to quote the FORMS, else they will be evaluated in the wrong environment, thus nullifying the intended protection. Not to mention that the second evaluation may cause errors, try for instance: (string-match "a+" "banana") (save-match-data (string-match "b+" "banana")) which should actually be (save-match-data '(string-match "b+" "banana")) A better way is to define a macro, to go along with the syntax of the special forms save-{excursion,restriction}. An example follows: (require 'cl) (defmacro save-match-data (&rest body) "Execute the BODY forms, restoring the global value of the match data." (let ((original (gensym))) (list 'let (list (list original '(match-data))) (list 'unwind-protect (cons 'progn body) (list 'store-match-data original))))) (put 'save-match-data 'lisp-indent-hook 0) In whose case we see (macroexpand '(save-match-data (string "n+" "banana"))) (let ((G$$_5 (match-data))) (unwind-protect (progn (string "n+" "banana")) (store-match-data G$$_5))) as desired. A minor optimization would be to generate the 'progn only if the body has 2 or more forms, but that would be most likely a waste of time. Cesar -- Cesar Augusto Quiroz Gonzalez Department of Computer Science University of Rochester Rochester, NY 14627