Jump to content

retrieve a var name passed as an argument


Jef!

Recommended Posts

Is it possible to retrieve a var name passed as an argument without quoting the var in the first place?

 

 

Better too much details than not enough; To illustrate..

Lets say the symbol Test is bound to 2

(defun ArgMonitor (arg);
(alert (strcat (vl-symbol-name arg) " contains: " (vl-princ-to-string (eval arg))))
(princ))

Command: (argmonitor 'test)

or also working command: (argmonitor (quote test))

A popup then appear with that text : TEST contains: 2

 

 

This is the exactly (the kind of) result I want to achieve, but my goal is to get the same result without the quote. The reason is that I want to turn that in a lambda, enclosed within a function that would accept a list of vars to monitor at the same time. That function would then send every item of the list to the lambda...but since it seems impossible to make a list of quoted symbols (list 'tmp 'test) returns (TMP TEST), it looks like I'm in a dead end, unless I can achieve the same without quoting the vars in the first place.

 

 

As always, any advice, suggestion or workaround is welcome

Cheers, Jef!

 

 

Edit: I thought of using mapcar but returned a strange result with quote.

Command: (setq tmp '(foo test1 cake))

(FOO TEST1 CAKE)

Command: (mapcar 'quote tmp)

((quote CAKE) (quote CAKE) (quote CAKE))

Edited by Jef!
added info
Link to comment
Share on other sites

Hi Jef,

 

If just to avoid putting quotes

have you tried this?

 

 

(setq FOO 1 TEST1 2 CAKE 3) ; sets each variable

(mapcar '(lambda (x) (argMonitor (eval (quote x))))
'(FOO TEST1 CAKE) )

;so do you mean this?
;FOO contains 1
;TEST1 contains 2
;CAKE contains 3


Link to comment
Share on other sites

The argument will need to be supplied as a quoted symbol, otherwise the symbol passed as an argument is evaluated and only the value bound to the symbol is passed to the subfunction, with no reference to the symbol passed as an argument.

 

To perform the operation on a list of variables:

(defun symval ( sym )
   (print sym) (princ "contains ") (prin1 (eval sym))
   (princ)
)

(setq foo 1 bar 2 baz 3)
(mapcar 'symval '(foo bar baz))

Or

(setq foo 1 bar 2 baz 3)
(mapcar 'symval  (list 'foo 'bar 'baz))

Link to comment
Share on other sites

Thanks for your input!

@hanhphuc: Not bad. It requires a pre-established and constant list though.

 

 

The target was to be able to monitor any variable/any number of variable and being able to put it anywhere within an existing function. Lets say at a specific point in execution I would like to monitor variables a b and e, I wanted to be able to do it with something as simple as (argmonitor a b e).

With your examples in mind I managed to do exactly what I need, being very user-friendly to launch. It pauses the execution at that point and show me the vars I want to check in one popup.. Here'S what I made.

Setting some vars:

(setq foo 1 bar 2 baz 3)

(defun Varmonitor (lst / alerttxt)
   (mapcar '(lambda ( sym )
              (if (null alerttxt)
                  (setq alerttxt ""))
              (setq alerttxt (strcat alerttxt(vl-princ-to-string sym) " contains " (vl-princ-to-string (eval sym)) "\n"))
                 (if (equal (last lst) sym)
                     (progn (alert alerttxt) (setq alerttxt nil)
                     )
                 )
              (princ)
            )
    lst
    )
   (princ)
 )

Launch with:

(varmonitor '(foo bar baz niltest))

 

 

I tried mapcar but I think that I forgot to quote the lambda. Now that it is working no matters what the var contains (string integer, real...), the only thing I could want to add is that that function launch the next one, so I could stick it into a if without having to add a prong statement

ie.: to go from

...

(if (= 2 foo)

(anyfunction arg))

to

...

(if (= 2 foo)

(varmonitor '(foo bar baz niltest) (anyfunction arg)))

so I could monitor while not having to add progns and without affecting the rest of the execution.. but I'm not sure if that could be done. I'm happy with what I have so far, but it would be awesome.
Link to comment
Share on other sites

No need for the alerttxt variable, just use the return of mapcar, e.g.:

(defun varmonitor ( lst )
   (alert
       (apply 'strcat
           (mapcar
              '(lambda ( sym )
                   (strcat
                       (vl-princ-to-string sym) " contains "
                       (vl-prin1-to-string (eval sym)) "\n"
                   )
               )
               lst
           )
       )
   )
)

I would also use vl-prin1-to-string for the variable value output so that string values are printed in AutoLISP format.

 

Be careful with:

(if (equal (last lst) sym)
 (progn (alert alerttxt) (setq alerttxt nil)
 )
)

As you'll have trouble if a symbol appears more than once, e.g.:

(varmonitor '(foo niltest bar baz niltest))

 

Link to comment
Share on other sites

No need for the alerttxt variable, just use the return of mapcar.

Indeed. I really try to get rid of all variables. I can get stuck with one or 2 because sometimes I have a hard time controlling the return values. It's not always obvious how to .. (putting the alert before instead of inside...)

 

Be careful with:

(if (equal (last lst) sym)
 (progn (alert alerttxt) (setq alerttxt nil)
 )
)

As you'll have trouble if a symbol appears more than once, e.g.:

(varmonitor '(foo niltest bar baz niltest))

(inside AND with a nice flaw) You are so true! That's the kind of detail experience makes you see instantly. (I would have found it the day I would have used it in a situation like (varmonitor '(foo niltest bar baz niltest)) ) Very nice catch, and thanks for pointing it out.

I would also use vl-prin1-to-string for the variable value output so that string values are printed in AutoLISP format.

Nice one. With that I see "strings" instead of strings. I like that.

 

 

Thanks Lee!

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...