Variable argument functions

Variable argument functions

ss6153
Enthusiast Enthusiast
841 Views
5 Replies
Message 1 of 6

Variable argument functions

ss6153
Enthusiast
Enthusiast

Hello Reader

I have defined a function called test like this:
(defun test ( str1 x y text1 text2)                        ---(1)

I am getting the values for (1) by reading a csv file and calling the function like this:

(test name (read x1) (read x2) text1 text2)      ---(2)

I want this function to take variable number of texts so I redefined it like this:

(defun test ( str1 x y &rest text)                         

 

How should I modify (2) such that variable number of texts can be read from the file and passed to the function?

 

Please help..

0 Likes
Accepted solutions (1)
842 Views
5 Replies
Replies (5)
Message 2 of 6

Kent1Cooper
Consultant
Consultant

@ss6153 wrote:

....

I want this function to take variable number of texts ....

How should I modify (2) such that variable number of texts can be read from the file and passed to the function?

....


I'm not aware of a way to do that.  As far as I know, functions with arguments need to have a known number of them, which is why if you don't supply the known number when calling the function, you get a "too few arguments" or "too many arguments" error.  Could it determine too few or too many if it isn't looking for a specific number?

 

I would think the way to do it is to read in the "number of texts" and assign them to variables inside the routine.  You don't say whether they're comma-delimited in one line in the .csv file, or from separate lines in it.  In either case, it will probably involve a (while) function, either to step through the comma-delimited pieces or to read the lines in the file.  You can set an indeterminate number of variables using the (set) function:

 

(setq varno 0); initial value to be stepped up each time

(while (setq txt {get next text element, by whatever means})

  (set (read (strcat "var" (itoa (setq varno (1+ varno))))) {txt directly, or something calculated from it})

); while

 

That should [untested] set the first text element pulled into the variable var1, the next into var2, etc., as long as there are text elements to pull.  Then use those variables in whatever the routine needs to do.

 

 

Kent Cooper, AIA
Message 3 of 6

ВeekeeCZ
Consultant
Consultant
Accepted solution

The proper way would be to use a list of texts. A list could be as long as needed.

'("text1" "text2" ... )

Message 4 of 6

pbejse
Mentor
Mentor

@ss6153 wrote:

How should I modify (2) such that variable number of texts can be read from the file and passed to the function?

 

Please help..


Hello poster

 

If you'll be needing absolutely everything on the csv, might as well read the contents/collect/store the values in a variable list. It doesnt take that long really. This also avoids issues with the file being locked [Yes it can happen with CSV as well ]  when something else goes wrong.

 

But If you are targetting a specific value on the csv file, process the values from the csv right after every read-line and stop reading when the target is reach. 

 

But that's just me.

 


@ss6153 wrote:

I want this function to take variable number of texts so I redefined it like this:

(defun test ( str1 x y &rest text)         


If you insist on doing that. always use a list as an argument format after processing the data from read-line.

that gives you unlimited number of values to be used in conjunction with foreach/mapcar/while/repeat... you know what i mean right?

 

Hope this helps

 

Message 5 of 6

john.uhden
Mentor
Mentor

Correct!

If fp is the file pointer variable...

(while (setq line (read-line fp))
  (setq lst (@str2list line " "))
  ;; do whatever you want with the lst
)
;;where...
  ;; Function to convert a string with delimiters into a list
  ;; pat is the delimiter and can contain multiple characters
   (defun @str2list (str pat / i j n lst)
     (cond
       ((/= (type str)(type pat) 'STR))
       ((= str pat)'(""))
       (T
         (setq i 0 n (strlen pat))
         (while (setq j (vl-string-search pat str i))
           (setq lst (cons (substr str (1+ i)(- j i)) lst)
                 i (+ j n)
           )
         )
         (reverse (cons (substr str (1+ i)) lst))
       )
     )
   )

John F. Uhden

Message 6 of 6

ss6153
Enthusiast
Enthusiast

Hi @john.uhden @pbejse @Kent1Cooper @ВeekeeCZ 
Thankyou all for your detailed explanations, I really appreciate it. 
As @ВeekeeCZ has suggested, I also felt that using this approach to get what I wanted seemed too long and complicated for a beginner like me. 
I really appreciate your quick and detailed response.. thankyou so much.


I do have a question related to my new approach - https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/read-a-line-from-csv-from-index-2-to...

Please help me if you can..thankyou

0 Likes