飞诗(fsxm) 发表于 2009-11-23 21:36:00

[原创]巧用出错,让你的程序更优雅。

出错程序就自然中断,再常见不过!
又没有想过好好利用一下呢?
下面用就好好利用出错中断的特性包装成两个函数!
;;无声退出
(defun fsxm-silenceexit (/ *error*)
(t (setq *error* strcat))
)
解说fsxm-silenceexit
这个是我最常用到的一个函数了!
有了它,代码会更优雅!
比如最常用的结构
(defun c:test ()
(setq ss (ssget))
(if ss
    (progn
   ........主程序模块........
    )
)
)
;;使用fsxm-silenceexit的
(defun c:test ()
(setq ss (ssget))
(or ss (fsxm-silenceexit))
........主程序模块........
)
绝大多数要求用户输入,都要检查数据合法性。
这样处理去了一层难看的括号,程序条理更分明!

;;带return的apply
(defun Fsxm-Apply ($Sym $Lst / $$ return $rt)
(defun Return (var) (setq Return nil) (setq $$ var) (exit))
(setq $rt (vl-catch-all-apply $Sym $Lst))
(if Return $rt $$)
)
解说Fsxm-Apply
一般说来Lisp的函数,只能一路执行到底,返回函数最后一个表达式的值。
试试Fsxm-Apply!集成一个类似于C语言的return功能!让你随时随地的结束函数,返回值!
特别应用就是在深层递归中退出。
如下例:找到第一个适合的文件就能立刻退出
用法:
(fsxm-searchfile 目录 文字样板 限时)
(fsxm-searchfile "c:" "*.lsp" 10)
;;查找一个文件
(defun fsxm-searchfile (path pate time / t0 t1 dir)
(defun dir (paths / find lst paths2 strcat_ph)
    (defun strcat_ph (lst)
      (mapcar '(lambda (a) (strcat ph "\\" a)) lst)
    )
    (while paths
      (setq paths2 nil)
      (foreach ph paths
(if (> (getvar "TDUSRTIMER") t1)
   (return nil)
)    ;超时退出
(if (setq find (vl-directory-files ph pate))
   (return (strcat ph "\\" (car find)))
)    ;找到退出
(if (and (setq lst (vl-directory-files ph nil -1))
   (if (= (car lst) ".")
   (setq lst (cddr lst))
   t
   )
   )
   (setq paths2 (cons (strcat_ph lst) paths2))
)
      )
      (setq paths (apply 'append paths2))
    )
)
(setq path (list path))
(setq t0 (getvar "TDUSRTIMER"))
(setq t1 (+ t0 (/ time 86400.0)))
(fsxm-apply 'dir (list path))
)
注:FSTL各版本的函数库都收录有以上函数。

啵浪鼓 发表于 2009-11-23 21:54:00

<p>自已做程序時都沒做出錯部分處理,程序運行後出錯了就按Esc鍵顯示一堆錯誤提示,太現眼了,現在可以借鑒樓上方式了!感謝樓主分享!!!</p>

carrot1983 发表于 2009-11-25 08:55:00

<p>占个位子学习一下。</p><p>很漂亮的除错语句。</p>

wangqin 发表于 2009-12-3 15:55:00

版主的水平就是不一样

Andlu-king 发表于 2009-12-13 20:50:00

不错,可免得没有出错程序而引起的不爽,谢谢分享,有时间时也试试!

飞的妖儿 发表于 2010-6-5 14:22:00

谢谢 楼主辛苦了!!!!

飞的妖儿 发表于 2010-6-5 14:30:00

我啥时候才能有这水平啊!

highflybird 发表于 2010-9-3 20:19:00

谢谢楼主,呵呵, 我把这个方法推广到国外去了。
举了一个例子:

(defun c:test()
(fsxm-apply 'func '((1 2 3 4 7 9 5 6 7 8 9)))
)
;;
(defun func (lst / i)
(setq i 0)
(foreach n lst
    (if (= n 5)
      (returni)
    )
    (setq i (1+ i))
)
nil
)
本来foreach 是遍历函数的,意味从头到尾,在这个例子中,func如果没有return函数,它的返回值总是nil,
正是因为有了return 函数,才使得函数在这点打断,返回了一个指定的值,使得函数得到了正确的返回值。然后因此引起的由主程序catch。
很好的思路,不过有点点遗憾的是 用到了vl-catch-all-apply,有可能会造成异常无法区分。
另外不知道楼主怎样对待 break,continue,和goto语句的呢?

zxjing 发表于 2011-1-15 17:07:06

我先占个坑,将来好LS,哈哈

USER2128 发表于 2011-11-22 21:29:57

经典好贴!
页: [1] 2 3
查看完整版本: [原创]巧用出错,让你的程序更优雅。