cwake 发表于 2022-7-6 00:19:26

套用比尔·克莱默的一本关于Lisp程序的书
在VisualLISP的上下文中,一切都是一个符号。当符号用于保存值时,它被称为变量。当符号用于保存函数定义列表时,它被称为函数
所以是的,当你定位一个变量(读作“符号”)时,不管它持有什么,它都有相同的效果。
我试着从VLIDE上传一些截图,在加载LISP并调用它运行后显示这三个符号的内容,但论坛没有玩球。所以我将在文本中尝试模仿这一点:
 
加载例程后:
*错误*=#
C: TESTALIAS=#
质量=#
 
这表明这三个功能(用户SUBR)很好。
 
但是在调用例程之后:
*误差*=零
C: TESTALIAS=#
质量=零
 
本地化的两个符号显示为nil。因此,是的,本地化包含函数的符号将使其无法使用。
 
这意味着,如果希望其他函数可以使用这些函数,请保持例程不变,但从局部符号列表中删除函数名。
 
或者,在主defun的外括号内定义函数,如下所示。
(defun c:TESTALIAS ( / *error* massoc ent elist typ laypipe layalias laycolor alias)
;------------------------------------------------------------------
(defun *error* (msg)
   (if (not (member msg '("Function cancelled" "quit / exit abort")))
   (princ (strcat "\nError: " msg))
   )
   (princ)
   )
;------------------------------------------------------------------
(defun massoc ( key lst / item )
   (if (setq item (assoc key lst))
   (cons (cdr item) (massoc key (cdr (member item lst))))
   )
   )
;------------------------------------------------------------------

(while (setq ent (entsel "\nSelect CADmep object: "))
   (progn
   (setq elist (entget (car ent))
         typ (cdr (assoc 0 elist))
         )
   (if (= typ "MAPS_SOLID")
       (progn
         (setq laypipe (cdr (assoc 8 elist))
               layalias (strcat laypipe "-TEXT")
               laycolor (cdr (assoc 62 (tblsearch "LAYER" laypipe)))
               alias (nth 4 (massoc 300 elist))
               )
         (if (null (tblsearch "LAYER" layalias))
         (progn
             (entmake (list '(0 . "LAYER")
                            '(100 . "AcDbSymbolTableRecord")
                            '(100 . "AcDbLayerTableRecord")
                            (cons 2 layalias)
                            '(70 . 0)
                            (cons 62 laycolor)
                            '(6 . "Continuous")
                            '(290 . 1)
                            '(370 . 25)
                            )
                      )
             (setvar "clayer" layalias)
             )
         (setvar "clayer" layalias)
         )
         (command "mleader" pause pause alias)
         )
       (prompt "\nNot a CADmep object.")
       )
   )
   )
(princ)
)

Jef! 发表于 2022-7-6 00:23:16

非常有趣。谢谢分享!
 
当你本地化一个变量(读作“符号”)时,不管它包含什么,它都具有相同的效果。该语句有点可疑,因为它似乎没有相同的效果,这取决于符号存储的是变量还是函数。如果我们以这个简单的例程为例
然后我们定义一个符号来包含一个具有不同值的全局变量x,比如22,然后运行测试例程。包含函数变量x的“局部”符号将存储33,然后被解除。但是,包含外部定义的全局变量x的符号将保留并保持其值。
可能是因为如果在主命令中定义了massoc(在主命令中声明为局部),则没有massoc,但另一个简单的测试表明,符号在存储变量或子函数时的反应不同。 
让我们尝试另一个测试,将符号x定义为局部变量,而不在例程中重新定义它。
6
同样的结果,定义的包含全局变量x的符号仍然保留。。。而如果执行的函数将所述符号声明为局部变量,则包含子函数(已定义)的符号将失去其定义。 
除非有什么我忽略了要考虑的,否则我不同意这样的说法:“当你定位一个变量(读作“符号”)时,不管它持有什么,它都有相同的效果。”
非常非常有趣的线程。
 
@ksperopoulos:如果你从c:TESTALIAS的局部符号中删除massoc,它有效吗?

cwake 发表于 2022-7-6 00:28:40

嗨,杰夫,
 
谢谢你的评论。我可能不擅长解释这些事情。
 
如果我在我的解释中添加以下内容会有所帮助:一旦主函数C:TESTALIAS完成,您将再次看到绑定到相关函数的符号*ERROR*和MASSOC?
 
如下所示:
 
*错误*=#
C: TESTALIAS=#
质量=#
 
只有在函数运行时(并且这些符号在正在执行的函数的上下文中是“局部的”),符号才似乎失去了定义。同时,在函数之外,这些变量仍然存在并保持其全局值。
这正是你在上一篇文章中举例子时提到的。

ksperopoulos 发表于 2022-7-6 00:31:01

 
对当我从局部变量中删除massoc时,程序就像预期的那样工作。
 
 
当您的代码中有*error*子函数时,您没有本地化它吗?

Jef! 发表于 2022-7-6 00:36:30

当然你很擅长解释!有时,即使一些概念或语境需要进一步澄清才能完全理解,但这并不意味着解释者不擅长。LISP和VisualLISP很复杂,掌握每件事并不总是显而易见的。
现在一切都有意义了。
如果您声明一个局部符号,就像我的所有示例一样,您可以使用任何已经定义的符号,而不会影响它们。如果在函数中声明局部符号并调用该符号,它将查找局部变量。如果到你使用它的时候还没有定义,那么问题就来了。
7
比尔·克莱默(BillKramer)是对的:所以无论符号包含变量还是函数,它们的反应都是一样的。 
 
是否本地化*错误*符号?当你这样做的时候,我打赌你在函数的第一行定义了它?
 
 
好我还有很多东西要学。我阅读并根据需要学习函数,每天都会发现新的东西、概念和函数。我甚至还没有掌握“误差”函数的概念。这是我的任务清单,也是我下一个里程碑。

ksperopoulos 发表于 2022-7-6 00:39:36

LeeMac在他的网站上有一些关于错误处理的好文章。他这样做,即使是我也能理解(至少我认为我理解)!我在等李拿出一本关于这方面的书。我要买他的第一本!
页: 1 [2]
查看完整版本: 子功能放置