AutoLisp 2021 参数太少错误(应用(lambda
AutoLisp 2021 Too few arguments error on (apply (lambda
我们已经安装了最新的 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
'(
("2" . "\\\\")
("\n" . "\\P")
("" . "\\(\\[ACcFfHKkLlOopQTW])|\\[ACcFfHKkLlOopQTW][^\\;]*;|\\[ACcFfKkHLlOopQTW]")
("/" . "([^\\])\\S([^;]*)[/#\^]([^;]*);")
("" . "\\(\\S)|[\\](})|}")
("" . "[\\]({)|{")
("\" . "(\\[ACcFfHKkLlOoPpQSTW])|({)|(})")
("\\" . "2")
("" . "(?:.*\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
)
)
这个函数的调用如下。我检查了 "input",它与 2019 版本相同,并且使用 vlisp (vscode) 调试器正确填充了 str。我有 运行 相同的代码并通过两者输入,只有 2021 版本失败?
(setq input (GDD:removeinfo (vlax-get-or-create-object "VBScript.RegExp") input))
我对 LISP 不是很熟悉,所以我被卡住了。感谢您的帮助。
假设 <FUN>
代表:
'(lambda nil
(vlax-put-property rgx 'global actrue)
(vlax-put-property rgx 'multiline actrue)
(vlax-put-property rgx 'ignorecase acfalse)
(foreach pair
'(("2" . "\\\\")
("\n" . "\\P")
("" . "\\(\\[ACcFfHKkLlOopQTW])|\\[ACcFfHKkLlOopQTW][^\\;]*;|\\[ACcFfKkHLlOopQTW]")
("/" . "([^\\])\\S([^;]*)[/#\^]([^;]*);")
("" . "\\(\\S)|[\\](})|}")
("" . "[\\]({)|{")
("\" . "(\\[ACcFfHKkLlOoPpQSTW])|({)|(})")
("\\" . "2")
("" . "(?:.*\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))
特别是,对 APPLY
的调用只有一个参数:
(apply <FUN>)
APPLY
在 Autolisp 中是一个有两个参数的函数:一个函数和一个参数列表。
目的是:
(apply f '(0 1))
... 就像您调用 (f 0 1)
一样进行评估,但有可能在运行时构建参数列表。
您在代码中只给 apply
一个参数,因此您还需要传递一个参数列表。
在您的情况下,那将是空列表:
(apply <FUN> nil)
不要将 vl-catch-all-apply
更改为 apply
以查看错误,只需将错误输出为 else 分支的一部分 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% 的代码用于我的功能并删除我的标题和作者前缀。
编写该代码的人似乎不知道 progn
运算符。
也就是说,如果我们要评估多个表达式 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)
将 value
放入 str
中,然后产生该值作为结果。它是 progn
(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))
我们已经安装了最新的 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
'(
("2" . "\\\\")
("\n" . "\\P")
("" . "\\(\\[ACcFfHKkLlOopQTW])|\\[ACcFfHKkLlOopQTW][^\\;]*;|\\[ACcFfKkHLlOopQTW]")
("/" . "([^\\])\\S([^;]*)[/#\^]([^;]*);")
("" . "\\(\\S)|[\\](})|}")
("" . "[\\]({)|{")
("\" . "(\\[ACcFfHKkLlOoPpQSTW])|({)|(})")
("\\" . "2")
("" . "(?:.*\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
)
)
这个函数的调用如下。我检查了 "input",它与 2019 版本相同,并且使用 vlisp (vscode) 调试器正确填充了 str。我有 运行 相同的代码并通过两者输入,只有 2021 版本失败?
(setq input (GDD:removeinfo (vlax-get-or-create-object "VBScript.RegExp") input))
我对 LISP 不是很熟悉,所以我被卡住了。感谢您的帮助。
假设 <FUN>
代表:
'(lambda nil
(vlax-put-property rgx 'global actrue)
(vlax-put-property rgx 'multiline actrue)
(vlax-put-property rgx 'ignorecase acfalse)
(foreach pair
'(("2" . "\\\\")
("\n" . "\\P")
("" . "\\(\\[ACcFfHKkLlOopQTW])|\\[ACcFfHKkLlOopQTW][^\\;]*;|\\[ACcFfKkHLlOopQTW]")
("/" . "([^\\])\\S([^;]*)[/#\^]([^;]*);")
("" . "\\(\\S)|[\\](})|}")
("" . "[\\]({)|{")
("\" . "(\\[ACcFfHKkLlOoPpQSTW])|({)|(})")
("\\" . "2")
("" . "(?:.*\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))
特别是,对 APPLY
的调用只有一个参数:
(apply <FUN>)
APPLY
在 Autolisp 中是一个有两个参数的函数:一个函数和一个参数列表。
目的是:
(apply f '(0 1))
... 就像您调用 (f 0 1)
一样进行评估,但有可能在运行时构建参数列表。
您在代码中只给 apply
一个参数,因此您还需要传递一个参数列表。
在您的情况下,那将是空列表:
(apply <FUN> nil)
不要将 vl-catch-all-apply
更改为 apply
以查看错误,只需将错误输出为 else 分支的一部分 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% 的代码用于我的功能并删除我的标题和作者前缀。
编写该代码的人似乎不知道 progn
运算符。
也就是说,如果我们要评估多个表达式 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)
将 value
放入 str
中,然后产生该值作为结果。它是 progn
(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))