[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Need some education on defmacro define-toggle

From: Pascal J. Bourguignon
Subject: Re: Need some education on defmacro define-toggle
Date: Mon, 28 Dec 2009 22:33:49 +0100
User-agent: Gnus/5.101 (Gnus v5.10.10) Emacs/22.3 (gnu/linux)

Lennart Borgman <address@hidden> writes:

> On Mon, Dec 28, 2009 at 6:16 AM, Lennart Borgman
> <address@hidden> wrote:
>> I just got into some trouble because of a badly written macro I
>> believe. After the long discussions about defmacro here I wonder if
>> anyone wants to help me out. How should I write the defmacro below?
> I resorted to self education (which is not too bad). However I still
> got problems - just on a more complicated level. The macro now looks
> like this:
> (defmacro define-toggle (symbol value doc &rest args)
>   "Declare SYMBOL as a customizable variable with a toggle function."
>   (declare   (doc-string 3)   (debug t))
>   (let* ((SYMBOL-toggle (intern (concat (symbol-name symbol) "-toggle")))
>          (SYMBOL-name (symbol-name symbol))
>          (var-doc doc)
>          (fun-doc (concat "Toggles the \(boolean) value of `" SYMBOL-name
>                           "'.\nFor how to set it permanently see this
> variable.\n")))
>     (let ((var (append `(defcustom ,symbol ,value ,var-doc)
>                 args
>                 nil))
>           (fun `(defun ,SYMBOL-toggle ()
>                    ,fun-doc
>                    (interactive)
>                    (customize-set-variable (quote ,symbol) (not ,symbol)))))
>       `(list 'progn ,var ,fun))))
> This seems to work, but if the call to define-toggle already has been
> done then loading a file with this define-toggle gives trouble:
> Debugger entered--Lisp error: (void-variable 
> rngalt-display-validation-header-toggle)
>   (progn rngalt-display-validation-header 
> rngalt-display-validation-header-toggle)
>   (define-toggle rngalt-display-validation-header t "Display XML validation 
> headers at the top of buffer when t.\nThe validation header is only displayed 
> in buffers where the main\nmajor mode is derivd from `nxml-mode'." :set 
> (lambda (sym val) (set-default sym val) 
> (rngalt-update-validation-header-overlay-everywhere)) :group (quote relax-ng) 
> :group (quote nxhtml))
> ...
> There is obviously something I got wrong in the evaluation order since
> now, in this situation, the macro now tries to evaluate
>   (progn rngalt-display-validation-header 
> rngalt-display-validation-header-toggle)
> I expected it to redefine the defcustom and the defun instead.
> Can someone please try to explain what is going on?

There must be an eval somewhere that tries to evaluate one time too many.

That said, why doesn't your macro just return 

   `(progn ,var ,fun)

instead of returning a list form that evaluates to something such as

   (progn rngalt-display-validation-header 

that needs to be evaluated (and of course fails since you didn't
define these symbols as variables)?

__Pascal Bourguignon__           

reply via email to

[Prev in Thread] Current Thread [Next in Thread]