乐筑天下

搜索
欢迎各位开发者和用户入驻本平台 尊重版权,从我做起,拒绝盗版,拒绝倒卖 签到、发布资源、邀请好友注册,可以获得银币 请注意保管好自己的密码,避免账户资金被盗
查看: 37|回复: 6

[编程交流] 代码#039;s系统变量

[复制链接]

66

主题

1552

帖子

1514

银币

后起之秀

Rank: 20Rank: 20Rank: 20Rank: 20

铜币
325
发表于 2022-7-5 17:21:31 | 显示全部楼层 |阅读模式
大家好,我正试图找到存储和重置系统变量列表的最短方法。但是,我不是列表操作专家,因此我需要一些mapcar和lambda函数的帮助:
  1. (defun C:test ( / vars )
  2. ; declare the list of variable names where each item is: (var-name-X new-var-val-X):
  3. (setq vars '(("FILLETRAD" 10) ("CLIPROMPTLINES" 1) ("OSMODE" 0) ("CMDECHO" 0)))
  4. ; this should reconstruct the list where each item is: (var-name-X old-varval-X new-var-val-X)):
  5. (setq vars (mapcar '(lambda (x) (list (car x) (getvar (car x)) (cadr x)) vars)))
  6. ; set the new values:
  7. (mapcar '(lambda (x) (setvar (car x) (caddr x)) vars))
  8. ; perform var-check:
  9. (foreach x vars
  10.         (princ (strcat (car x) " with value: " (getvar (car x))))
  11. )
  12. (alert "\nThe main function starts!")
  13. ; restore the variable values:
  14. (mapcar '(lambda (x) (setvar (car x) (cadr x)) vars))
  15. ; perform var-check:
  16. (foreach x vars
  17.         (princ (strcat (car x) " with value: " (getvar (car x))))
  18. )
  19. (princ)
  20. ); defun

目标是只设置一个名为“vars”的引号,而不是为每个系统变量设置一组引号。所以我们都可以从中受益
 
换句话说(一些测试是从visual lisp控制台复制的):
  1. _$ ; declare the list of variable names "vars" where each item is: (var-name-X new-var-val-X):
  2. (setq vars '(("FILLETRAD" 10) ("CLIPROMPTLINES" 1) ("OSMODE" 0) ("CMDECHO" 0)))
  3. (("FILLETRAD" 10) ("CLIPROMPTLINES" 1) ("OSMODE" 0) ("CMDECHO" 0))
  4. _$ ; this should reconstruct the list to "nvars" where each item is: (var-name-X old-varval-X new-var-val-X)):
  5. (setq nvars (list))
  6. nil
  7. _$
  8. _$ (foreach itm vars
  9. (if (not (member (car itm) (mapcar 'car nvars)))
  10.         (setq nvars (cons (list (car itm) (getvar (car itm)) (cadr itm)) nvars))
  11. )
  12. )
  13. (("CMDECHO" 1 0) ("OSMODE" 15359 0) ("CLIPROMPTLINES" 4 1) ("FILLETRAD" 52.0 10))
  14. _$ (setq nvars (reverse nvars))
  15. (("FILLETRAD" 52.0 10) ("CLIPROMPTLINES" 4 1) ("OSMODE" 15359 0) ("CMDECHO" 1 0))
  16. _$ ; set the new values:
  17. (foreach itm nvars
  18. (setvar (car itm) (caddr itm))
  19. (princ (strcat "\n" (car itm) " : " (rtos (getvar (car itm)))))
  20. )
  21. FILLETRAD : 10.0000
  22. CLIPROMPTLINES : 1.0000
  23. OSMODE : 0.0000
  24. CMDECHO : 0.0000"\nCMDECHO : 0.0000"
  25. _$ (alert "\nThe main function starts!")
  26. nil
  27. _$ ; restore the variable values:
  28. (foreach itm nvars
  29. (setvar (car itm) (cadr itm))
  30. (princ (strcat "\n" (car itm) " : " (rtos (getvar (car itm)))))
  31. )
  32. FILLETRAD : 52.0000
  33. CLIPROMPTLINES : 4.0000
  34. OSMODE : 15359.0000
  35. CMDECHO : 1.0000"\nCMDECHO : 1.0000"
  36. _$

但在这里,我使用了两个引号“vars”和“nvars”-我的问题是,是否可以将其缩短为仅一个“vars”并可能进行一些覆盖(使用mapcar/lambda而不是我的新手foreach方法)。
回复

使用道具 举报

106

主题

1万

帖子

101

银币

顶梁支柱

Rank: 50Rank: 50

铜币
1299
发表于 2022-7-5 17:34:00 | 显示全部楼层
只需我将列表简化一点(list“FILLETRAD”10“CLIPROMPTLINES”1“OSMODE”0“CMDECHO”0)
 
然后只需使用一个重复函数,即长度/2,nth x是变量名,nth x+1是值。
 
如果需要,可以创建两个列表,并通过正确的列表名调用单个defun。
 
有时我会迷失在兰巴的世界里,所以我不确定德芬会变短多少,或者会有什么真正的收获。
 
  1. (defun c:myvars ( / vars)
  2. (setq vars (list "FILLETRAD" 10 "CLIPROMPTLINES" 1 "OSMODE" 0 "CMDECHO" 0))
  3. (myvars vars)
  4. )
  5. (defun C:myvarsu ( / varsu )
  6. (setq varsu (list "FILLETRAD" 10 "CLIPROMPTLINES" 1 "OSMODE" 47 "CMDECHO" 1))
  7. (myvars varsu)
  8. )
  9. (defun myvars ( vars / x)
  10. (setq x 0)
  11. (repeat (/ (length vars) 2)
  12. (setq sysvar (nth x vars))
  13. (setq sysval (nth (+ x 1) vars))
  14. (command sysvar sysval)
  15. (setq x (+ x 2))
  16. )
  17. )
回复

使用道具 举报

26

主题

1495

帖子

20

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
118
发表于 2022-7-5 17:42:43 | 显示全部楼层
我使用点对
 
  1. ;++++++++++++ Set Modes ++++++++++++++++++++++++++++++++++
  2. (defun nw_smd ()
  3. (setq nw_var '(("CMDECHO"   . 0) ("MENUECHO"   . 0)
  4.                ("MENUCTL"   . 0) ("MACROTRACE" . 0)
  5.                ("OSMODE"    . 0) ("SORTENTS"   . 119)
  6.                ("LUPREC"    . 2) ("MODEMACRO"  . ".")
  7.                ("BLIPMODE"  . 0) ("EXPERT"     . 5)
  8.                ("SNAPMODE"  . 1) ("PLINEWID"   . 0)
  9.                ("ORTHOMODE" . 1) ("GRIDMODE"   . 0)
  10.                ("ELEVATION" . 0) ("THICKNESS"  . 0)
  11.                ("FILEDIA"   . 0) ("FILLMODE"   . 0)
  12.                ("SPLFRAME"  . 0) ("UNITMODE"   . 0)
  13.                ("TEXTEVAL"  . 0) ("ATTDIA"     . 0)
  14.                ("AFLAGS"    . 0) ("ATTREQ"     . 1)
  15.                ("ATTMODE"   . 1) ("UCSICON"    . 1)
  16.                ("HIGHLIGHT" . 1) ("REGENMODE"  . 1)
  17.                ("COORDS"    . 2) ("DRAGMODE"   . 2)
  18.                ("DIMZIN"    .  ("PDMODE"     . 0)
  19.                ("SNAPUNIT"  . (1 1))
  20.                ("CECOLOR"   . "BYLAYER")
  21.                ("CELTYPE"   . "BYLAYER")))
  22. (foreach v nw_var
  23.   (and (getvar (car v))
  24.        (setq nw_rst (cons (cons (car v) (getvar (car v))) nw_rst))
  25.        (setvar (car v) (cdr v))))
  26. (princ))
  27. ;++++++++++++ Return Modes +++++++++++++++++++++++++++++++
  28. (defun nw_rmd ()
  29. (foreach v nw_rst (setvar (car v) (cdr v)))
  30. (prin1))

 
我喜欢有条理的感觉。
 
-大卫
回复

使用道具 举报

114

主题

1万

帖子

1万

银币

中流砥柱

Rank: 25

铜币
543
发表于 2022-7-5 17:55:08 | 显示全部楼层
 
就个人而言,我建议在存储现有系统变量值时不要覆盖“vars”变量,因为如果遇到错误,还需要在局部错误处理程序中包含一个表达式来重置系统变量。因此,通过使用相同的变量名,您需要依赖于对不同列表结构的测试,以确定“vars”变量是否包含存储的系统变量值或新值(因为在存储现有值之前或之后可能会遇到错误)。
 
相反,我建议使用单独的变量来存储现有值,例如:
但是,有时您不想同时更改列表中所有系统变量的值,因此以下方法可能更合适:
请注意,上述示例还测试在获取现有系统变量值时getvar表达式是否返回非零值,因为并非所有系统变量在所有版本的AutoCAD中都可用。
 
 
我必须说,使用foreach没有什么“新手”的地方;在许多解决方案中,foreach是任务最合适的函数,例如:如果您在列表中迭代项目,并且在处理项目时不使用返回的值,那么foreach比mapcar更合适。
回复

使用道具 举报

66

主题

1552

帖子

1514

银币

后起之秀

Rank: 20Rank: 20Rank: 20Rank: 20

铜币
325
发表于 2022-7-5 18:03:31 | 显示全部楼层
谢谢你们的帮助!
李,我修改了你的建议(感谢你发布它们和你对这个主题的质疑)。
 
我对您提供的代码进行了一些修改和测试,最终得到了这个(评论版):
[code]defun c:test/*error*varsdefun*error*msg([/color b]princ“\n>>发生错误!恢复变量!“princ“\n”foreach x varsgetvarcar xsetvarcar xcaddr x [颜色=蓝色][color=绿色][color=褐红色][color=深蓝色][color=深蓝色];分配原始值[color]foreach xmapcar‘car varsprinc:“b]prin1getvar xprinc“\n”;执行打印检查[[color]princ;在这里,用户构建一个关联列表,其中每个项目包含setq VAR([/color b]filletrad 10)[/color b]=MAROON](clipromptlines 1osmode 0CMDCecho 0princ“\n>>原始变量:“princ“\n”foreach xmapcar'car varsprinc:”[/colorprin1getvar x princ“\n”;如果不是tempvars如果不是tempvars;检查是否没有此类全局变量ifsetq tempvars;临时将列表分配给该变量mapcar'lambdax/v[=紫色]([/colorsetq vgetvarcar xlistcar x)[/color b]cadr x[v varsprognsetq vars tempvars;重新引用“vars”列表[color]setq tempvars nil;删除全局变量princ“\n>>代码已启动!更改变量:“[/color b]princ“\n”[color][COLO=FUCHSIA])foreach x varsifgetvarcar xsetvarcar xcadr x)[/颜色 [颜色=紫红色];分配新值[color]foreach xmapcar'car varsprin1 xprinc:“([/color b]prin1 b]getvar xprinc“\n”;要执行打印检查,getstring t“\n输入内容:\n”;<执行操作>princ“\n>>还原变量:“]princ”\n“foreach x vars如果getvarcar xsetvarcar x[caddr x)[/color b];分配原始值[color]foreach xmapcar'car varsprin1 xprinc:“([/color b]prib]getvar xprinc“\n”;要执行打印检查,代码结束!
回复

使用道具 举报

114

主题

1万

帖子

1万

银币

中流砥柱

Rank: 25

铜币
543
发表于 2022-7-5 18:19:31 | 显示全部楼层
致各
回复

使用道具 举报

66

主题

1552

帖子

1514

银币

后起之秀

Rank: 20Rank: 20Rank: 20Rank: 20

铜币
325
发表于 2022-7-5 18:25:50 | 显示全部楼层
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).
回复

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

  • 微信公众平台

  • 扫描访问手机版

  • 点击图片下载手机App

QQ|关于我们|小黑屋|乐筑天下 繁体中文

GMT+8, 2025-3-13 04:52 , Processed in 0.457419 second(s), 66 queries .

© 2020-2025 乐筑天下

联系客服 关注微信 帮助中心 下载APP 返回顶部 返回列表