明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 4585|回复: 14

[经验] Lisp程序结构

[复制链接]
发表于 2014-10-15 14:17 | 显示全部楼层 |阅读模式
个人经验,主要写给自己

;;在明经混了许多年,又在晓东混了几年了,渐发现原来写的程序不是太合理,全改又没有那么多精力了.   
;;对于lisp程序结构,我自己有了自己的看法,自己总结一下,今后套用这种格式。 自贡黄明儒 2014.10.15

;;1 建立通用和自定义函数库,分别保存为Public.lsp和MyLsp.lsp,今后加载和修改就方便了
;;今后只需要加载两个文件,这就方便了;通用函数的建立,给自己修改来方便。

;;2 自定函数
(defun C:w1 (/ CMD1 OSM1 SS)
  ;;2.1 错误处理
  ;;定义在函数内部,作用范围也只限于此函数。
  ;;写在开头,以保证后面的代码发生错误,均会执行错误处理。
  (defun *error* (msg)
    ;;2.1.1 写在开头,错误处理反跟踪,找出调试错误所在。调试完毕后,可注释掉
    (vl-bt)
    ;;2.1.2 如果命令还在执行,中断它
    (while (not (equal (getvar "cmdnames") "")) (command nil))
    ;;2.1.3 在错误发生之前改变的变量,发生错误时后面的代码不再执行,必须恢复
    (setvar "nomutt" 0);容量忘了它,没恢复成0后面使用起来怪怪的
    (cond (cmd1 (setvar 'cmdecho cmd1)))
    (cond (osm1 (setvar 'osmode osm1)))   
    (princ "\n 出错啦!")
    ;;2.1.4 静默退出
    (princ)
  )

  ;;2.2 其它临时函数,非通用的
  ()
  
  ;;2.3 一般说来,执行一个程序,总是要选择对象。如果希望先择后执行,就要有这句,而且写在开头
  (cond ((cadr (ssgetfirst)) (setq ss (ssget "_P" '((0 . "*TEXT"))))))
  ;;2.4 检查加载vl扩展,有这句没有坏处,也不会造成程序多大的额外负担,因为如果已经加载扩展,不做任何事情
  (VL-LOAD-COM)  
  ;;2.5 *acad* *DOC*是常用的,不必释放。前面加*号,编辑器检查形参时会把它们排在前面,便于我们去除
  (or *acad* (setq *acad* (vlax-get-acad-object)))
  (or *DOC* (setq *DOC* (vla-get-ActiveDocument *acad*)))
  ;;2.6 获取并修改变量
  (setq cmd1 (getvar "cmdecho"));如果后面用到command,不希望显示一些信息
  (setvar "cmdecho" 0)
  (setq osm1 (getvar "osmode"));如果后面用到command画图,不关闭捕捉,就可能不是我们需要的点
  (setvar "osmode" 0)
  ;;2.7 编组开始
  ;;便于按后悔键Ctrl+Z时,一步退到位

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

x

点评

个人认为CMDECHO直接定义为0就可以了,没有恢复原值的必要  发表于 2014-10-15 16:28

评分

参与人数 4明经币 +5 收起 理由
longer1000 + 1 赞一个!
434939575 + 1 谢谢分享!
机械工程师 + 1 多谢分享经验
Gu_xl + 2 赞一个!

查看全部评分

"觉得好,就打赏"
还没有人打赏,支持一下

本帖被以下淘专辑推荐:

发表于 2014-10-15 15:57 | 显示全部楼层
我以前没读过书,现在来上成人扫盲班还来得及
发表于 2014-10-15 16:19 | 显示全部楼层
*acad*不释放还可以 *DOC*总是用一个的话,多文档环境下,文档一切换就有问题了。

补充一点个人经验,我们做代码,可维护性要放在更高的位置。变量、函数的命名情愿长一点,要体现其含义,多注释; 多写短小的代码; 每个函数功能尽可能单一,提高函数的利用率;

比如代码超过二、三十行,局部变量超过五、六个的函数,就看下有没有可能拆分成几个函数,对于维护和提高代码的质量都大有好处

点评

lisp变量在每个文档都不同的,*DOC*跟文档切换无关,可以不用释放  发表于 2014-10-17 09:19

评分

参与人数 2明经币 +2 收起 理由
飞诗(fsxm) + 1 lisp变量在每个文档都不同的,*DOC*跟文档切.
自贡黄明儒 + 1 高手呀!!

查看全部评分

发表于 2014-10-15 17:08 | 显示全部楼层
很好,实用,谢谢
 楼主| 发表于 2014-10-16 09:26 | 显示全部楼层
vectra 发表于 2014-10-15 16:19
*acad*不释放还可以 *DOC*总是用一个的话,多文档环境下,文档一切换就有问题了。

补充一点个人经验,我 ...

现在是不是妥了

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

x
发表于 2014-10-16 10:24 | 显示全部楼层
提点改进意见:
1、如果每个自定函数都要定义这么复杂,而且相似程度又高的*error*函数,那么,提取出该函数公共的、相似的部分,做成一个通用函数,比如public-error-handler;自定义函数中的*error*只是简单地引用public-error-handler。一切为了“减少允余”原则。

2、 建议*error*放在局部变量表中去,貌似可以不影响全局错误函数,可以完全不干涉CAD的错误处理机制。(未深入测试,参LEE-MAC代码)

3、   (cond (*doc* (vlax-release-object *doc*)))
没有必要,*doc*还是建议做成局部变量,退出就释放了;document是CAD自己维护的,也不可能释放掉。vlax-release-object只在用户启动的外部对象时需要,如excel什么的。

4、(gc)可以取消,lisp文档较缺,机制不明确。但根据.net的资料,频繁强制回收内存会造成性能问题。还是多检查局部变量,意外的全局变量即使GC也不能回收。

5、 (defun c:w1 ()..)的做法并不太好,考虑别人也有个命令,也定义成了W1,甚至都VLX封闭了。可以定义为MyCustomFunctionA,然后再通过别名或者重定义命令调用。当然简单的应用也不用考虑这么多啦

6、没有sel-method参数的ssget本身支持先命令或先选择的方式,试下(ssget '((0 . "*TEXT")))

7、变量设置可参考gxl-error-init函数 http://bbs.mjtd.com/forum.php?mod=viewthread&tid=100616
 楼主| 发表于 2014-10-16 10:50 | 显示全部楼层
本帖最后由 自贡黄明儒 于 2014-10-16 10:54 编辑
vectra 发表于 2014-10-16 10:24
提点改进意见:
1、如果每个自定函数都要定义这么复杂,而且相似程度又高的*error*函数,那么,提取出该函 ...

第2条,内外都可以放一个*error*函数,都会执行的。
最后一条,是G版的,整得很复杂,看得人头晕
发表于 2014-10-16 13:13 | 显示全部楼层
学习了,现在还没有这么复杂的程序,不过也许正是没有做到上面这些,使得自己做不了复杂程序
发表于 2014-10-16 13:40 | 显示全部楼层
请继续,洗耳恭听
发表于 2014-10-16 16:38 | 显示全部楼层
用下面的代码简单测试了下

  1. (defun *error* (s)
  2.   (princ "1")
  3. )

  4. (defun test (/ *error*)
  5.   (defun *error* (s)
  6.     (princ "2")
  7.   )

  8.   (/ 1 0)
  9. )


; 2 表格 从 #<editor "<未命名-0> 正在加载..."> 加载
_$ *error*
#<USUBR @0c5a74ec *ERROR*>
_$ (test)
2
_$ *error*
#<USUBR @0c5a74ec *ERROR*>
_$ (test)
2
_$ (/ 1 0)
1


可见,test内的错误由test内部定义的*error*处理,而在test函数外部的错误由外面定义的*error处理。没有看到同时调用内外部*error*的情况

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

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-4-26 19:00 , Processed in 0.286647 second(s), 31 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表