Mercurial > hg > xemacs-beta
comparison man/lispref/specifiers.texi @ 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 | 05ed51332340 |
children | ec2d1e636272 |
comparison
equal
deleted
inserted
replaced
1868:1c5756d02f31 | 1869:11812ec0334c |
---|---|
36 particular value is valid. | 36 particular value is valid. |
37 * Retrieving Specifications:: Querying a specifier's specifications. | 37 * Retrieving Specifications:: Querying a specifier's specifications. |
38 * Specifier Tag Functions:: Working with specifier tags. | 38 * Specifier Tag Functions:: Working with specifier tags. |
39 * Specifier Instancing Functions:: | 39 * Specifier Instancing Functions:: |
40 Functions to instance a specifier. | 40 Functions to instance a specifier. |
41 * Specifier Example:: Making all this stuff clearer. | 41 * Specifier Examples:: Making all this stuff clearer. |
42 * Creating Specifiers:: Creating specifiers for your own use. | 42 * Creating Specifiers:: Creating specifiers for your own use. |
43 * Specifier Validation Functions:: | 43 * Specifier Validation Functions:: |
44 Validating the components of a specifier. | 44 Validating the components of a specifier. |
45 * Other Specification Functions:: | 45 * Other Specification Functions:: |
46 Other ways of working with specifications. | 46 Other ways of working with specifications. |
1044 @var{specifier}. If the instantiation fails, @var{default} is returned. | 1044 @var{specifier}. If the instantiation fails, @var{default} is returned. |
1045 In most circumstances, you should not use this function; use | 1045 In most circumstances, you should not use this function; use |
1046 @code{specifier-instance} instead. | 1046 @code{specifier-instance} instead. |
1047 @end defun | 1047 @end defun |
1048 | 1048 |
1049 @node Specifier Example | 1049 @node Specifier Examples |
1050 @section Example of Specifier Usage | 1050 @section Examples of Specifier Usage |
1051 | 1051 |
1052 Now let us present an example to clarify the theoretical discussions we | 1052 Now let us present an example to clarify the theoretical discussions we |
1053 have been through. In this example, we will use the general specifier | 1053 have been through. In this example, we will use the general specifier |
1054 functions for clarity. Keep in mind that many types of specifiers, and | 1054 functions for clarity. Keep in mind that many types of specifiers, and |
1055 some other types of objects that are associated with specifiers | 1055 some other types of objects that are associated with specifiers |
1118 call the instantiation method for colors. This time, the X server | 1118 call the instantiation method for colors. This time, the X server |
1119 our window is on recognizes the color @samp{moccasin}, and so the | 1119 our window is on recognizes the color @samp{moccasin}, and so the |
1120 instantiation method succeeds and returns a color instance. | 1120 instantiation method succeeds and returns a color instance. |
1121 @end enumerate | 1121 @end enumerate |
1122 | 1122 |
1123 Here's another example, which implements something like GNU Emacs's | |
1124 ``frame-local'' variables. | |
1125 | |
1126 @example | |
1127 ;; Implementation | |
1128 | |
1129 ;; There are probably better ways to write this macro | |
1130 ;; Heaven help you if VAR is a buffer-local; you will become very | |
1131 ;; confused. Probably should error on that. | |
1132 (defmacro define-frame-local-variable (var) | |
1133 "Make the unbound symbol VAR become a frame-local variable." | |
1134 (let ((val (if (boundp var) (symbol-value var) nil))) | |
1135 `(progn | |
1136 (setq ,var (make-specifier 'generic)) | |
1137 (add-spec-to-specifier ,var ',val 'global)))) | |
1138 | |
1139 ;; I'm not real happy about this terminology, how can `setq' be a defun? | |
1140 ;; But `frame-set' would have people writing "(frame-set 'foo value)". | |
1141 (defun frame-setq (var value &optional frame) | |
1142 "Set the local value of VAR to VALUE in FRAME. | |
1143 | |
1144 FRAME defaults to the selected frame." | |
1145 (and frame (not (framep frame)) | |
1146 (error 'invalid-argument "FRAME must be a frame", frame)) | |
1147 (add-spec-to-specifier var value (or frame (selected-frame)))) | |
1148 | |
1149 (defun frame-value (var &optional frame) | |
1150 "Get the local value of VAR in FRAME. | |
1151 | |
1152 FRAME defaults to the selected frame." | |
1153 (and frame (not (framep frame)) | |
1154 (error 'invalid-argument "FRAME must be a frame", frame)) | |
1155 ;; this is not just a map from frames to values; it also falls back | |
1156 ;; to the global value | |
1157 (specifier-instance var (or frame (selected-frame)))) | |
1158 | |
1159 ;; for completeness | |
1160 (defun frame-set-default (var value) | |
1161 "Set the default value of frame-local variable VAR to VALUE." | |
1162 (add-spec-to-specifier var value 'global)) | |
1163 | |
1164 (defun frame-get-default (var) | |
1165 "Get the default value of frame-local variable VAR." | |
1166 (car (specifier-specs var 'global))) | |
1167 @end example | |
1168 | |
1169 Now you can execute the above definitions (eg, with @code{eval-last-sexp}) | |
1170 and switch to @file{*scratch*} to play. Things will work differently if | |
1171 you already have a variable named @code{foo}. | |
1172 | |
1173 @example | |
1174 ;; Usage | |
1175 | |
1176 foo | |
1177 @error{} Symbol's value as variable is void: foo | |
1178 | |
1179 (define-frame-local-variable foo) | |
1180 @result{} nil | |
1181 | |
1182 ;; the value of foo is a specifier, which is an opaque object; | |
1183 ;; you must use accessor functions to get values | |
1184 | |
1185 foo | |
1186 @result{} #<generic-specifier global=(nil) 0x4f5cb> | |
1187 | |
1188 ;; since no frame-local value is set, the global value (which is the | |
1189 ;; constant `nil') is returned | |
1190 (frame-value foo) | |
1191 @result{} nil | |
1192 | |
1193 ;; get the default explicitly | |
1194 (frame-get-default foo) | |
1195 @result{} nil | |
1196 | |
1197 ;; get the whole specification list | |
1198 (specifier-specs foo 'global) | |
1199 @result{} (nil) | |
1200 | |
1201 ;; give foo a frame-local value | |
1202 | |
1203 (frame-setq foo 'bar) | |
1204 @result{} nil | |
1205 | |
1206 ;; access foo in several ways | |
1207 | |
1208 ;; Note that the print function for this kind of specifier only | |
1209 ;; gives you the global setting. To get the full list of specs for | |
1210 ;; debugging or study purposes, you must use specifier-specs or | |
1211 ;; specifier-spec-list. | |
1212 foo | |
1213 @result{} #<generic-specifier global=(nil) 0x4f5cb> | |
1214 | |
1215 ;; get the whole specification list | |
1216 (specifier-specs foo) | |
1217 @result{} ((#<x-frame "Message" 0x1bd66> (nil . bar)) (global (nil))) | |
1218 | |
1219 ;; get the frame-local value | |
1220 (frame-value foo) | |
1221 @result{} bar | |
1222 | |
1223 ;; get the default explicitly | |
1224 (frame-get-default foo) | |
1225 @result{} nil | |
1226 | |
1227 ;; Switch to another frame and evaluate: | |
1228 ;; C-x 5 o M-: (frame-setq foo 'baz) RET M-: (frame-value foo) RET | |
1229 @result{} baz | |
1230 | |
1231 ;; Switch back. | |
1232 ;; C-x 5 o | |
1233 (specifier-specs foo) | |
1234 @result{} ((#<x-frame "emacs" 0x28ec> (nil . baz)) | |
1235 (#<x-frame "Message" 0x1bd66> (nil . bar)) | |
1236 (global (nil))) | |
1237 | |
1238 (frame-value foo) | |
1239 @result{} bar | |
1240 | |
1241 (frame-get-default foo) | |
1242 @result{} nil | |
1243 @end example | |
1244 | |
1245 Note that since specifiers generalize both frame-local and buffer-local | |
1246 variables in a sensible way, XEmacs is not likely to put a high priority | |
1247 on implementing frame-local variables. | |
1248 @c Thanks to Jerry James for the following explanation. He is not | |
1249 @c responsible for its use here, Stephen Turnbull is. | |
1250 In fact, some developers think that frame-local variables are evil for | |
1251 the same reason that buffer-local variables are evil: the declaration is | |
1252 both global and invisible. That is, you cannot tell whether a variable | |
1253 is ``normal,'' buffer-local, or frame-local just by looking at it. So | |
1254 if you have namespace management problems, and some other Lisp package | |
1255 happens to use a variable name that you already declared frame- or | |
1256 buffer-local, weird stuff happens, and it is extremely hard to track | |
1257 down. | |
1258 | |
1259 | |
1123 @node Creating Specifiers | 1260 @node Creating Specifiers |
1124 @section Creating New Specifier Objects | 1261 @section Creating New Specifier Objects |
1125 | 1262 |
1126 @defun make-specifier type | 1263 @defun make-specifier type |
1127 This function creates a new specifier. | 1264 This function creates a new specifier. |