Search code examples
lispautodeskautolisp

AutoLisp 2021 Too few arguments error on (apply (lambda


We have installed the latest Autodesk 2021 and one of our scripts (a modified @Lee Mac) which strips and formats some input text now fails. This script runs perfectly on 2019 and below. I can't seem to work out why there is a difference.

I have substituted the original "vl-catch-all-apply" to "apply" so I could catch the error. The error is:

Too few arguments

This occurs as it hits the '(lambda function call. The code is below with the call:

(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
)
)

The call to this function is below. I've checked the "input" and it is identical to the 2019 version that works and the str is populated properly using the vlisp (vscode) debugger. I've run the same code and input through both and only the 2021 version fails?

(setq input (GDD:removeinfo (vlax-get-or-create-object "VBScript.RegExp") input))

I'm not that familiar with LISP and I'm stuck. Thanks for your help.


Solution

  • Assuming <FUN> stands for:

    '(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)))))
    

    The code you posted, rewritten more compactly, looks as follows:

    (defun GDD:removeinfo (rgx str)
      (if (null (vl-catch-all-error-p
                 (setq str (apply <FUN>))))
          str))
    

    In particular, the call to APPLY has only one argument:

    (apply <FUN>)
    

    APPLY in Autolisp is a function of 2 parameters: a function, and a list of arguments.

    The intent is that:

    (apply f '(0 1))
    

    ... is evaluated as-if you called (f 0 1), but with possibility of building the list of arguments at runtime.

    You only gave one argument to apply in your code, so you need to also pass a list of arguments. In your case, that would be the empty list:

    (apply <FUN> nil)