Mercurial > hg > xemacs-beta
changeset 1869:11812ec0334c
[xemacs-hg @ 2004-01-21 09:03:42 by stephent]
email change <87vfn5zndg.fsf@tleepslib.sk.tsukuba.ac.jp>
specifier example <8765f62dl0.fsf@tleepslib.sk.tsukuba.ac.jp>
author | stephent |
---|---|
date | Wed, 21 Jan 2004 09:03:47 +0000 |
parents | 1c5756d02f31 |
children | 375ec21c9374 |
files | man/ChangeLog man/lispref/lispref.texi man/lispref/specifiers.texi man/xemacs-faq.texi |
diffstat | 4 files changed, 155 insertions(+), 6 deletions(-) [+] |
line wrap: on
line diff
--- a/man/ChangeLog Tue Jan 20 22:51:19 2004 +0000 +++ b/man/ChangeLog Wed Jan 21 09:03:47 2004 +0000 @@ -1,3 +1,15 @@ +2004-01-20 Stephen J. Turnbull <stephen@xemacs.org> + + * lispref/specifiers.texi (Specifier Examples): Add new example, + pluralize node name and section title. + (Specifiers): Pluralize "Specifier Examples" in menu. + + * lispref/lispref.texi (Top): Pluralize "Specifier Examples" in menu. + +2003-11-04 Stephen J. Turnbull <stephen@xemacs.org> + + * xemacs-faq.texi: Fix Tony Rossini's address. + 2003-12-15 Steve Youngs <sryoungs@bigpond.net.au> * lispref/customize.texi (Defining New Types): New node.
--- a/man/lispref/lispref.texi Tue Jan 20 22:51:19 2004 +0000 +++ b/man/lispref/lispref.texi Wed Jan 21 09:03:47 2004 +0000 @@ -946,7 +946,7 @@ * Retrieving Specifications:: Querying a specifier's specifications. * Specifier Instancing Functions:: Functions to instance a specifier. -* Specifier Example:: Making all this stuff clearer. +* Specifier Examples:: Making all this stuff clearer. * Creating Specifiers:: Creating specifiers for your own use. * Specifier Validation Functions:: Validating the components of a specifier.
--- a/man/lispref/specifiers.texi Tue Jan 20 22:51:19 2004 +0000 +++ b/man/lispref/specifiers.texi Wed Jan 21 09:03:47 2004 +0000 @@ -38,7 +38,7 @@ * Specifier Tag Functions:: Working with specifier tags. * Specifier Instancing Functions:: Functions to instance a specifier. -* Specifier Example:: Making all this stuff clearer. +* Specifier Examples:: Making all this stuff clearer. * Creating Specifiers:: Creating specifiers for your own use. * Specifier Validation Functions:: Validating the components of a specifier. @@ -1046,8 +1046,8 @@ @code{specifier-instance} instead. @end defun -@node Specifier Example -@section Example of Specifier Usage +@node Specifier Examples +@section Examples of Specifier Usage Now let us present an example to clarify the theoretical discussions we have been through. In this example, we will use the general specifier @@ -1120,6 +1120,143 @@ instantiation method succeeds and returns a color instance. @end enumerate +Here's another example, which implements something like GNU Emacs's +``frame-local'' variables. + +@example +;; Implementation + +;; There are probably better ways to write this macro +;; Heaven help you if VAR is a buffer-local; you will become very +;; confused. Probably should error on that. +(defmacro define-frame-local-variable (var) + "Make the unbound symbol VAR become a frame-local variable." + (let ((val (if (boundp var) (symbol-value var) nil))) + `(progn + (setq ,var (make-specifier 'generic)) + (add-spec-to-specifier ,var ',val 'global)))) + +;; I'm not real happy about this terminology, how can `setq' be a defun? +;; But `frame-set' would have people writing "(frame-set 'foo value)". +(defun frame-setq (var value &optional frame) + "Set the local value of VAR to VALUE in FRAME. + +FRAME defaults to the selected frame." + (and frame (not (framep frame)) + (error 'invalid-argument "FRAME must be a frame", frame)) + (add-spec-to-specifier var value (or frame (selected-frame)))) + +(defun frame-value (var &optional frame) + "Get the local value of VAR in FRAME. + +FRAME defaults to the selected frame." + (and frame (not (framep frame)) + (error 'invalid-argument "FRAME must be a frame", frame)) + ;; this is not just a map from frames to values; it also falls back + ;; to the global value + (specifier-instance var (or frame (selected-frame)))) + +;; for completeness +(defun frame-set-default (var value) + "Set the default value of frame-local variable VAR to VALUE." + (add-spec-to-specifier var value 'global)) + +(defun frame-get-default (var) + "Get the default value of frame-local variable VAR." + (car (specifier-specs var 'global))) +@end example + +Now you can execute the above definitions (eg, with @code{eval-last-sexp}) +and switch to @file{*scratch*} to play. Things will work differently if +you already have a variable named @code{foo}. + +@example +;; Usage + +foo +@error{} Symbol's value as variable is void: foo + +(define-frame-local-variable foo) +@result{} nil + +;; the value of foo is a specifier, which is an opaque object; +;; you must use accessor functions to get values + +foo +@result{} #<generic-specifier global=(nil) 0x4f5cb> + +;; since no frame-local value is set, the global value (which is the +;; constant `nil') is returned +(frame-value foo) +@result{} nil + +;; get the default explicitly +(frame-get-default foo) +@result{} nil + +;; get the whole specification list +(specifier-specs foo 'global) +@result{} (nil) + +;; give foo a frame-local value + +(frame-setq foo 'bar) +@result{} nil + +;; access foo in several ways + +;; Note that the print function for this kind of specifier only +;; gives you the global setting. To get the full list of specs for +;; debugging or study purposes, you must use specifier-specs or +;; specifier-spec-list. +foo +@result{} #<generic-specifier global=(nil) 0x4f5cb> + +;; get the whole specification list +(specifier-specs foo) +@result{} ((#<x-frame "Message" 0x1bd66> (nil . bar)) (global (nil))) + +;; get the frame-local value +(frame-value foo) +@result{} bar + +;; get the default explicitly +(frame-get-default foo) +@result{} nil + +;; Switch to another frame and evaluate: +;; C-x 5 o M-: (frame-setq foo 'baz) RET M-: (frame-value foo) RET +@result{} baz + +;; Switch back. +;; C-x 5 o +(specifier-specs foo) +@result{} ((#<x-frame "emacs" 0x28ec> (nil . baz)) + (#<x-frame "Message" 0x1bd66> (nil . bar)) + (global (nil))) + +(frame-value foo) +@result{} bar + +(frame-get-default foo) +@result{} nil +@end example + +Note that since specifiers generalize both frame-local and buffer-local +variables in a sensible way, XEmacs is not likely to put a high priority +on implementing frame-local variables. +@c Thanks to Jerry James for the following explanation. He is not +@c responsible for its use here, Stephen Turnbull is. +In fact, some developers think that frame-local variables are evil for +the same reason that buffer-local variables are evil: the declaration is +both global and invisible. That is, you cannot tell whether a variable +is ``normal,'' buffer-local, or frame-local just by looking at it. So +if you have namespace management problems, and some other Lisp package +happens to use a variable name that you already declared frame- or +buffer-local, weird stuff happens, and it is extremely hard to track +down. + + @node Creating Specifiers @section Creating New Specifier Objects
--- a/man/xemacs-faq.texi Tue Jan 20 22:51:19 2004 +0000 +++ b/man/xemacs-faq.texi Wed Jan 21 09:03:47 2004 +0000 @@ -7,9 +7,9 @@ @finalout @titlepage @title XEmacs FAQ -@subtitle Frequently asked questions about XEmacs @* Last Modified: $Date: 2003/10/10 12:39:27 $ +@subtitle Frequently asked questions about XEmacs @* Last Modified: $Date: 2004/01/21 09:03:42 $ @sp 1 -@author Tony Rossini <rossini@@biostat.washington.edu> +@author Tony Rossini <rossini@@u.washington.edu> @author Ben Wing <ben@@xemacs.org> @author Chuck Thompson <cthomp@@xemacs.org> @author Steve Baur <steve@@xemacs.org>