代码#039;s系统变量
大家好,我正试图找到存储和重置系统变量列表的最短方法。但是,我不是列表操作专家,因此我需要一些mapcar和lambda函数的帮助:(defun C:test ( / vars )
; declare the list of variable names where each item is: (var-name-X new-var-val-X):
(setq vars '(("FILLETRAD" 10) ("CLIPROMPTLINES" 1) ("OSMODE" 0) ("CMDECHO" 0)))
; this should reconstruct the list where each item is: (var-name-X old-varval-X new-var-val-X)):
(setq vars (mapcar '(lambda (x) (list (car x) (getvar (car x)) (cadr x)) vars)))
; set the new values:
(mapcar '(lambda (x) (setvar (car x) (caddr x)) vars))
; perform var-check:
(foreach x vars
(princ (strcat (car x) " with value: " (getvar (car x))))
)
(alert "\nThe main function starts!")
; restore the variable values:
(mapcar '(lambda (x) (setvar (car x) (cadr x)) vars))
; perform var-check:
(foreach x vars
(princ (strcat (car x) " with value: " (getvar (car x))))
)
(princ)
); defun
目标是只设置一个名为“vars”的引号,而不是为每个系统变量设置一组引号。所以我们都可以从中受益
换句话说(一些测试是从visual lisp控制台复制的):
_$ ; declare the list of variable names "vars" where each item is: (var-name-X new-var-val-X):
(setq vars '(("FILLETRAD" 10) ("CLIPROMPTLINES" 1) ("OSMODE" 0) ("CMDECHO" 0)))
(("FILLETRAD" 10) ("CLIPROMPTLINES" 1) ("OSMODE" 0) ("CMDECHO" 0))
_$ ; this should reconstruct the list to "nvars" where each item is: (var-name-X old-varval-X new-var-val-X)):
(setq nvars (list))
nil
_$
_$ (foreach itm vars
(if (not (member (car itm) (mapcar 'car nvars)))
(setq nvars (cons (list (car itm) (getvar (car itm)) (cadr itm)) nvars))
)
)
(("CMDECHO" 1 0) ("OSMODE" 15359 0) ("CLIPROMPTLINES" 4 1) ("FILLETRAD" 52.0 10))
_$ (setq nvars (reverse nvars))
(("FILLETRAD" 52.0 10) ("CLIPROMPTLINES" 4 1) ("OSMODE" 15359 0) ("CMDECHO" 1 0))
_$ ; set the new values:
(foreach itm nvars
(setvar (car itm) (caddr itm))
(princ (strcat "\n" (car itm) " : " (rtos (getvar (car itm)))))
)
FILLETRAD : 10.0000
CLIPROMPTLINES : 1.0000
OSMODE : 0.0000
CMDECHO : 0.0000"\nCMDECHO : 0.0000"
_$ (alert "\nThe main function starts!")
nil
_$ ; restore the variable values:
(foreach itm nvars
(setvar (car itm) (cadr itm))
(princ (strcat "\n" (car itm) " : " (rtos (getvar (car itm)))))
)
FILLETRAD : 52.0000
CLIPROMPTLINES : 4.0000
OSMODE : 15359.0000
CMDECHO : 1.0000"\nCMDECHO : 1.0000"
_$
但在这里,我使用了两个引号“vars”和“nvars”-我的问题是,是否可以将其缩短为仅一个“vars”并可能进行一些覆盖(使用mapcar/lambda而不是我的新手foreach方法)。 只需我将列表简化一点(list“FILLETRAD”10“CLIPROMPTLINES”1“OSMODE”0“CMDECHO”0)
然后只需使用一个重复函数,即长度/2,nth x是变量名,nth x+1是值。
如果需要,可以创建两个列表,并通过正确的列表名调用单个defun。
有时我会迷失在兰巴的世界里,所以我不确定德芬会变短多少,或者会有什么真正的收获。
(defun c:myvars ( / vars)
(setq vars (list "FILLETRAD" 10 "CLIPROMPTLINES" 1 "OSMODE" 0 "CMDECHO" 0))
(myvars vars)
)
(defun C:myvarsu ( / varsu )
(setq varsu (list "FILLETRAD" 10 "CLIPROMPTLINES" 1 "OSMODE" 47 "CMDECHO" 1))
(myvars varsu)
)
(defun myvars ( vars / x)
(setq x 0)
(repeat (/ (length vars) 2)
(setq sysvar (nth x vars))
(setq sysval (nth (+ x 1) vars))
(command sysvar sysval)
(setq x (+ x 2))
)
)
我使用点对
;++++++++++++ Set Modes ++++++++++++++++++++++++++++++++++
(defun nw_smd ()
(setq nw_var '(("CMDECHO" . 0) ("MENUECHO" . 0)
("MENUCTL" . 0) ("MACROTRACE" . 0)
("OSMODE" . 0) ("SORTENTS" . 119)
("LUPREC" . 2) ("MODEMACRO". ".")
("BLIPMODE". 0) ("EXPERT" . 5)
("SNAPMODE". 1) ("PLINEWID" . 0)
("ORTHOMODE" . 1) ("GRIDMODE" . 0)
("ELEVATION" . 0) ("THICKNESS". 0)
("FILEDIA" . 0) ("FILLMODE" . 0)
("SPLFRAME". 0) ("UNITMODE" . 0)
("TEXTEVAL". 0) ("ATTDIA" . 0)
("AFLAGS" . 0) ("ATTREQ" . 1)
("ATTMODE" . 1) ("UCSICON" . 1)
("HIGHLIGHT" . 1) ("REGENMODE". 1)
("COORDS" . 2) ("DRAGMODE" . 2)
("DIMZIN" .("PDMODE" . 0)
("SNAPUNIT". (1 1))
("CECOLOR" . "BYLAYER")
("CELTYPE" . "BYLAYER")))
(foreach v nw_var
(and (getvar (car v))
(setq nw_rst (cons (cons (car v) (getvar (car v))) nw_rst))
(setvar (car v) (cdr v))))
(princ))
;++++++++++++ Return Modes +++++++++++++++++++++++++++++++
(defun nw_rmd ()
(foreach v nw_rst (setvar (car v) (cdr v)))
(prin1))
我喜欢有条理的感觉。
-大卫
就个人而言,我建议在存储现有系统变量值时不要覆盖“vars”变量,因为如果遇到错误,还需要在局部错误处理程序中包含一个表达式来重置系统变量。因此,通过使用相同的变量名,您需要依赖于对不同列表结构的测试,以确定“vars”变量是否包含存储的系统变量值或新值(因为在存储现有值之前或之后可能会遇到错误)。
相反,我建议使用单独的变量来存储现有值,例如:
但是,有时您不想同时更改列表中所有系统变量的值,因此以下方法可能更合适:
请注意,上述示例还测试在获取现有系统变量值时getvar表达式是否返回非零值,因为并非所有系统变量在所有版本的AutoCAD中都可用。
我必须说,使用foreach没有什么“新手”的地方;在许多解决方案中,foreach是任务最合适的函数,例如:如果您在列表中迭代项目,并且在处理项目时不使用返回的值,那么foreach比mapcar更合适。 谢谢你们的帮助!
李,我修改了你的建议(感谢你发布它们和你对这个主题的质疑)。
我对您提供的代码进行了一些修改和测试,最终得到了这个(评论版):
(defun c:test(/*error*vars)(defun*error*(msg(princ“\n>>发生错误!恢复变量!“)(princ“\n”(foreach x vars(getvar(car x)(setvar(car x(caddr x [颜色=蓝色];分配原始值(foreach x(mapcar‘car vars)(princ:“)(b]prin1(getvar x)(princ“\n”;执行打印检查[(princ));在这里,用户构建一个关联列表,其中每个项目包含()(setq VAR;()((filletrad 10)=MAROON](clipromptlines 1)(osmode 0)(CMDCecho 0)(princ“\n>>原始变量:“(princ“\n”(foreach x(mapcar'car vars)(princ:”(prin1(getvar x (princ“\n”;如果(不是tempvars)(如果(不是tempvars);检查是否没有此类全局变量(if(setq tempvars;临时将列表分配给该变量(mapcar'(lambda(x/v)([=紫色](setq v(getvar(car x))(list(car x)(cadr x); ()vars(progn(setq vars tempvars);重新引用“vars”列表(setq tempvars nil);删除全局变量(princ“\n>>代码已启动!更改变量:“(princ“\n”)(foreach x vars(if(getvar(car x)(setvar(car x(cadr x)[/颜色 [颜色=紫红色];分配新值(foreach x(mapcar'car vars(prin1 x)(princ:“(prin1 b](getvar x)(princ“\n”;要执行打印检查,(getstring t“\n输入内容:\n”);<执行操作>(princ“\n>>还原变量:“](princ”\n“(foreach x vars(如果(getvar(car x)(setvar(car x));分配原始值(foreach x(mapcar'car vars(prin1 x)(princ:“(prib](getvar x)(princ“\n”;要执行打印检查,代码结束! 致各 Thanks alot Lee!
You offered several cases for someone to use for their codes - and more importantly: in the shortest way possible.
Basically you are everywhere in this LISP world... (atleast I know when something clever comes up in someone's code - no wonder you were the guy to figure it out first or atleast have been a part from it).
页:
[1]