AutoLisp 2021上的参数太少错误(应用(lambda

AutoLisp 2021上的参数太少错误(应用(lambda,lisp,autodesk,autolisp,Lisp,Autodesk,Autolisp,我们已经安装了最新的Autodesk 2021和我们的一个脚本(一个修改的@Lee Mac),其中一些输入文本的剥离和格式化现在失败了。该脚本在2019年及以下版本上运行得非常好。我似乎不明白为什么会有不同 我已将原来的“vl catch all apply”替换为“apply”,以便捕获错误。错误为: Too few arguments 这发生在它点击lambda函数调用时。调用代码如下: (defun GDD:removeinfo (rgx str) (if (null

我们已经安装了最新的Autodesk 2021和我们的一个脚本(一个修改的@Lee Mac),其中一些输入文本的剥离和格式化现在失败了。该脚本在2019年及以下版本上运行得非常好。我似乎不明白为什么会有不同

我已将原来的“vl catch all apply”替换为“apply”,以便捕获错误。错误为:

Too few arguments
这发生在它点击lambda函数调用时。调用代码如下:

(defun GDD:removeinfo (rgx str)
(if
    (null
        (vl-catch-all-error-p
            (setq str
                (apply
                   '(lambda nil
                        (vlax-put-property rgx 'global     actrue)
                        (vlax-put-property rgx 'multiline  actrue)
                        (vlax-put-property rgx 'ignorecase acfalse) 
                        (foreach pair
                           '(
                                ("\032"     . "\\\\\\\\")
                                ("\n"        . "\\\\P")
                                ("$1"       . "\\\\(\\\\[ACcFfHKkLlOopQTW])|\\\\[ACcFfHKkLlOopQTW][^\\\\;]*;|\\\\[ACcFfKkHLlOopQTW]")
                                ("$1$2/$3"  . "([^\\\\])\\\\S([^;]*)[/#\\^]([^;]*);")
                                ("$1$2"     . "\\\\(\\\\S)|[\\\\](})|}")
                                ("$1"       . "[\\\\]({)|{")
                                ("\\$1$2$3" . "(\\\\[ACcFfHKkLlOoPpQSTW])|({)|(})")
                                ("\\\\"     . "\032")
                                (""     . "(?:.*\\n)*Const\\s+.*\\n")
                                        (""     . "\\w\\w\\d?\\s+\\d+\\s\\d+-\\d+-\\d+")
                                        (""     . "^\\s+\\n")
                            )
                            (vlax-put-property rgx 'pattern (cdr pair))
                            (setq str (vlax-invoke rgx 'replace str (car pair)))
                        )
                    )
                )
            )
        )
    )
    str
)
)
下面是对该函数的调用。我已经检查了“输入”,它与2019版本相同,并且使用vlisp(vscode)调试器正确填充str。我已经通过这两个版本运行了相同的代码和输入,只有2021版本失败

(setq input (GDD:removeinfo (vlax-get-or-create-object "VBScript.RegExp") input))
我对LISP不太熟悉,我被卡住了。谢谢你的帮助。

假设
代表:

'(lambda nil
  (vlax-put-property rgx 'global     actrue)
  (vlax-put-property rgx 'multiline  actrue)
  (vlax-put-property rgx 'ignorecase acfalse) 
  (foreach pair
   '(("\032"     . "\\\\\\\\")
     ("\n"        . "\\\\P")
     ("$1"       . "\\\\(\\\\[ACcFfHKkLlOopQTW])|\\\\[ACcFfHKkLlOopQTW][^\\\\;]*;|\\\\[ACcFfKkHLlOopQTW]")
     ("$1$2/$3"  . "([^\\\\])\\\\S([^;]*)[/#\\^]([^;]*);")
     ("$1$2"     . "\\\\(\\\\S)|[\\\\](})|}")
     ("$1"       . "[\\\\]({)|{")
     ("\\$1$2$3" . "(\\\\[ACcFfHKkLlOoPpQSTW])|({)|(})")
     ("\\\\"     . "\032")
     (""     . "(?:.*\\n)*Const\\s+.*\\n")
     (""     . "\\w\\w\\d?\\s+\\d+\\s\\d+-\\d+-\\d+")
     (""     . "^\\s+\\n"))
   (vlax-put-property rgx 'pattern (cdr pair))
   (setq str (vlax-invoke rgx 'replace str (car pair)))))
您发布的代码更紧凑地重写,如下所示:

(defun GDD:removeinfo (rgx str)
  (if (null (vl-catch-all-error-p
             (setq str (apply <FUN>))))
      str))
在Autolisp中,有一个包含两个参数的函数:一个函数和一组参数

目的是:

(apply f '(0 1))
…的计算方式与调用
(f 0 1)
类似,但有可能在运行时生成参数列表

您在代码中只为
apply
提供了一个参数,因此还需要传递一个参数列表。 在您的情况下,这将是一个空列表:

(apply <FUN> nil)
(应用零)
假设
代表:

'(lambda nil
  (vlax-put-property rgx 'global     actrue)
  (vlax-put-property rgx 'multiline  actrue)
  (vlax-put-property rgx 'ignorecase acfalse) 
  (foreach pair
   '(("\032"     . "\\\\\\\\")
     ("\n"        . "\\\\P")
     ("$1"       . "\\\\(\\\\[ACcFfHKkLlOopQTW])|\\\\[ACcFfHKkLlOopQTW][^\\\\;]*;|\\\\[ACcFfKkHLlOopQTW]")
     ("$1$2/$3"  . "([^\\\\])\\\\S([^;]*)[/#\\^]([^;]*);")
     ("$1$2"     . "\\\\(\\\\S)|[\\\\](})|}")
     ("$1"       . "[\\\\]({)|{")
     ("\\$1$2$3" . "(\\\\[ACcFfHKkLlOoPpQSTW])|({)|(})")
     ("\\\\"     . "\032")
     (""     . "(?:.*\\n)*Const\\s+.*\\n")
     (""     . "\\w\\w\\d?\\s+\\d+\\s\\d+-\\d+-\\d+")
     (""     . "^\\s+\\n"))
   (vlax-put-property rgx 'pattern (cdr pair))
   (setq str (vlax-invoke rgx 'replace str (car pair)))))
您发布的代码更紧凑地重写,如下所示:

(defun GDD:removeinfo (rgx str)
  (if (null (vl-catch-all-error-p
             (setq str (apply <FUN>))))
      str))
在Autolisp中,有一个包含两个参数的函数:一个函数和一组参数

目的是:

(apply f '(0 1))
…的计算方式与调用
(f 0 1)
类似,但有可能在运行时生成参数列表

您在代码中只为
apply
提供了一个参数,因此还需要传递一个参数列表。 在您的情况下,这将是一个空列表:

(apply <FUN> nil)
(应用零)

不要将
vl catch all apply
更改为
apply
以查看错误,只需将错误作为
if
语句的else分支的一部分输出,例如:

(if
    (null
        (vl-catch-all-error-p
            (setq str
                (vl-catch-all-apply
                    ...
                )
            )
        )
    )
    str
    (prompt (strcat "\nError: " (vl-catch-all-error-message str))) ;; Output error and return nil
)


除此之外,虽然这段代码相对简单,但我不确定是否同意您将95%的代码用于我的函数,并去掉标题和作者前缀。

而不是将
vl catch all apply
更改为
apply
以查看错误,只需将错误作为的else分支的一部分输出即可ode>if语句,例如:

(if
    (null
        (vl-catch-all-error-p
            (setq str
                (vl-catch-all-apply
                    ...
                )
            )
        )
    )
    str
    (prompt (strcat "\nError: " (vl-catch-all-error-message str))) ;; Output error and return nil
)


除此之外,虽然这段代码相对来说微不足道,但我不确定是否同意您将95%的代码用于我的函数,并去掉我的标题和作者前缀。

编写该代码的人似乎不知道运算符

也就是说,如果我们想计算多个表达式,
e1
e2
,…为了它们产生的副作用,我们不必这样做:

;; wrap expressions in a dummy lambda and apply empty arg list to it
(apply (lambda () e1 e2 ...) nil)
我们可以这样写:

(progn e1 e2 ...)
这仍然给我们留下了一种奇怪的代码气味,看起来像这样:

(setq str (progn .... (setq str value)))
代码使用相同的值分配变量
str
两次。深嵌套的
(setq str value)
放入
str
,然后生成该值。它是
程序的最后一个表达式(最初是
lambda
)然后,外部的
setq
再次浪费地将其存储在
str
中。我们只需要其中一个:

;; set str as the side effect of the last form in the
;; progn; also yield that value.
(progn e1 e2 ...(setq str value))

;; assign value yielded from progn to str, then also
;; yield that value.
(setq str (progn e1 e2 ... value))

编写代码的人似乎不知道操作员

也就是说,如果我们想计算多个表达式,
e1
e2
,…为了它们产生的副作用,我们不必这样做:

;; wrap expressions in a dummy lambda and apply empty arg list to it
(apply (lambda () e1 e2 ...) nil)
我们可以这样写:

(progn e1 e2 ...)
这仍然给我们留下了一种奇怪的代码气味,看起来像这样:

(setq str (progn .... (setq str value)))
代码使用相同的值分配变量
str
两次。深嵌套的
(setq str value)
放入
str
,然后生成该值。它是
程序的最后一个表达式(最初是
lambda
)然后,外部的
setq
再次浪费地将其存储在
str
中。我们只需要其中一个:

;; set str as the side effect of the last form in the
;; progn; also yield that value.
(progn e1 e2 ...(setq str value))

;; assign value yielded from progn to str, then also
;; yield that value.
(setq str (progn e1 e2 ... value))

为简洁起见,我没有在帖子中包含函数调用的标题-这是在原始代码中。您会注意到,我在原始帖子中特别提到了这是您的脚本。如果没有明确说明,请道歉。只是为了让您知道if-else不起作用。一旦出现错误,它似乎就会从if语句中消失d(apply的参数太少)并且根本没有命中prompt else语句。我不确定为什么,因为您的建议看起来是正确的。我需要查看您对我的建议的实现,以确定错误的原因-请注意,
vl catch all apply正在评估的
lambda
函数不需要参数(如
nil
参数列表所示)-您在代码中看到的
nil
并没有像您在上面对coredump的评论中所说的那样作为参数提供。我已经在编辑中为您添加了实际实现。通过以下方式调用:(setq输入(GDD:removeinfo(vlax get或create object“VBScript.RegExp”)输入))为简洁起见,我没有在帖子中包含函数调用的标题-这是在原始代码中。您会注意到,我在原始帖子中特别提到了这是您的脚本。如果没有明确说明,请道歉。只是为了让您知道if-else不起作用。一旦出现错误,它似乎就会从if语句中消失d(应用的参数太少)并且根本没有命中prompt else语句。我不确定为什么,因为您的建议看起来是正确的。我需要查看您对我的建议的实施情况,以确定错误的原因-注意