From mboxrd@z Thu Jan 1 00:00:00 1970 Path: main.gmane.org!not-for-mail From: Luc Teirlinck Newsgroups: gmane.emacs.devel Subject: Re: void variable Date: Sun, 25 Jul 2004 15:46:15 -0500 (CDT) Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Message-ID: <200407252046.i6PKkFH29813@raven.dms.auburn.edu> References: <410353ED.1090107@math.ku.dk> <4104091E.4040007@math.ku.dk> NNTP-Posting-Host: deer.gmane.org X-Trace: sea.gmane.org 1090788593 17745 80.91.224.253 (25 Jul 2004 20:49:53 GMT) X-Complaints-To: usenet@sea.gmane.org NNTP-Posting-Date: Sun, 25 Jul 2004 20:49:53 +0000 (UTC) Cc: emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Sun Jul 25 22:49:44 2004 Return-path: Original-Received: from lists.gnu.org ([199.232.76.165]) by deer.gmane.org with esmtp (Exim 3.35 #1 (Debian)) id 1BopwF-0004Qq-00 for ; Sun, 25 Jul 2004 22:49:43 +0200 Original-Received: from localhost ([127.0.0.1] helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.33) id 1BopzF-0001rf-1M for ged-emacs-devel@m.gmane.org; Sun, 25 Jul 2004 16:52:49 -0400 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.33) id 1Bopz8-0001qq-Kf for emacs-devel@gnu.org; Sun, 25 Jul 2004 16:52:42 -0400 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.33) id 1Bopz7-0001qF-8O for emacs-devel@gnu.org; Sun, 25 Jul 2004 16:52:42 -0400 Original-Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.33) id 1Bopz7-0001qC-4n for emacs-devel@gnu.org; Sun, 25 Jul 2004 16:52:41 -0400 Original-Received: from [131.204.53.104] (helo=manatee.dms.auburn.edu) by monty-python.gnu.org with esmtp (Exim 4.34) id 1Bopw1-0003vE-IH for emacs-devel@gnu.org; Sun, 25 Jul 2004 16:49:29 -0400 Original-Received: from raven.dms.auburn.edu (raven.dms.auburn.edu [131.204.53.29]) by manatee.dms.auburn.edu (8.12.10/8.12.10) with ESMTP id i6PKnSuE002928; Sun, 25 Jul 2004 15:49:28 -0500 (CDT) Original-Received: (from teirllm@localhost) by raven.dms.auburn.edu (8.11.6+Sun/8.11.6) id i6PKkFH29813; Sun, 25 Jul 2004 15:46:15 -0500 (CDT) X-Authentication-Warning: raven.dms.auburn.edu: teirllm set sender to teirllm@dms.auburn.edu using -f Original-To: larsh@math.ku.dk In-reply-to: <4104091E.4040007@math.ku.dk> (message from Lars Hansen on Sun, 25 Jul 2004 21:25:18 +0200) X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: main.gmane.org gmane.emacs.devel:25948 X-Report-Spam: http://spam.gmane.org/gmane.emacs.devel:25948 Lars Hansen wrote: I now see that the docstring of defvar clearly says that the variable is set only if it is void. So (let ((foo 'y)) (defvar foo 'x)) should leave foo void as it does. It has nothing to do with the fact that defvar only sets the variable if void. You get the same result with: (let ((foo 'y)) (makunbound 'foo) (defvar foo 'x)) See the ielm run at the end of this posting. What it has to do with is the following quote from `(elisp)Defining Variables': *Warning:* If the `defconst' and `defvar' special forms are used while the variable has a local binding (made with `let', or a function argument), they set the local-binding's value; the top-level binding is not changed. This is not what you usually want. To prevent it, use these special forms at top level in a file, where normally no local binding is in effect, and make sure to load the file before making a local binding for the variable. This also applies to defcustom. So there is no problem :-) Unless other people might be confused by this too. Maybe it might be good to add the above warning to the involved docstrings. What about the following patches? ===File ~/eval.c-diff======================================= *** eval.c 19 Jul 2004 07:02:32 -0500 1.220 --- eval.c 25 Jul 2004 15:19:42 -0500 *************** *** 742,747 **** --- 742,754 ---- This means that M-x set-variable recognizes it. See also `user-variable-p'. If INITVALUE is missing, SYMBOL's value is not set. + + If SYMBOL has a local binding, then this form affects the local + binding. This is usually not what you want. Thus, if you need to + load a file defining variables, with this form or with `defconst' or + `defcustom', you should always load that file _outside_ any bindings + for these variables. \(`defconst' and `defcustom' behave similarly in + this respect.) usage: (defvar SYMBOL &optional INITVALUE DOCSTRING) */) (args) Lisp_Object args; *************** *** 784,789 **** --- 791,800 ---- If SYMBOL is buffer-local, its default value is what is set; buffer-local values are not affected. DOCSTRING is optional. + + If SYMBOL has a local binding, then this form sets the local binding's + value. However, you should normally not make local bindings for + variables defined with this form. usage: (defconst SYMBOL INITVALUE [DOCSTRING]) */) (args) Lisp_Object args; ============================================================ ===File ~/custom.el-diff==================================== *** custom.el 05 Jun 2004 22:41:36 -0500 1.75 --- custom.el 25 Jul 2004 15:19:30 -0500 *************** *** 246,251 **** --- 246,258 ---- Specifies that SYMBOL should be set after the list of variables VARIABLES when both have been customized. + If SYMBOL has a local binding, then this form affects the local + binding. This is normally not what you want. Thus, if you need + to load a file defining variables with this form, or with + `defvar' or `defconst', you should always load that file + _outside_ any bindings for these variables. \(`defvar' and + `defconst' behave similarly in this respect.) + Read the section about customization in the Emacs Lisp manual for more information." ;; It is better not to use backquote in this file, ============================================================ Just to illustrate: ===File ~/foo-ielm========================================== *** Welcome to IELM *** Type (describe-mode) for help. ELISP> (let ((foo 1)) (defvar foo 2) foo) 1 ELISP> (boundp 'foo) nil ELISP> (let ((foo 1)) (makunbound 'foo) (defvar foo 2) foo) 2 ELISP> (boundp 'foo) nil ELISP> (let ((foo 1)) (defconst foo 2) foo) 2 ELISP> (boundp 'foo) nil ELISP> (defvar foo 3) foo ELISP> (let ((foo 1)) (makunbound 'foo) (defvar foo 2) foo) 2 ELISP> foo 3 ELISP> (makunbound 'foo) foo ELISP> (let ((foo 1)) (makunbound 'foo) (defcustom foo 2 "blabla") foo) 2 ELISP> (boundp 'foo) nil ELISP> (defcustom foo 3 "blabla") foo ELISP> (let ((foo 1)) (makunbound 'foo) (defcustom foo 2 "blabla") foo) 2 ELISP> foo 3 ELISP> ============================================================