Patrick
Patrick

Reputation: 525

Defining a variable with a name that is kept in an other variable

I need to define a variable with a name contained in another variable.

The following code does not work and it uses eval, therefore not very good style.

(defvar symbol "zap")
(eval `(defvar ,symbol 100))
(print zap)

Upvotes: 1

Views: 236

Answers (4)

Rainer Joswig
Rainer Joswig

Reputation: 139261

use SET:

CL-USER 13 > (defvar *some-symbol* '*this-is-some-symbol*)
*SOME-SYMBOL*

CL-USER 14 > (set *some-symbol* 42)
42

CL-USER 15 > *this-is-some-symbol*
42

or if it is a string:

(setf (symbol-value (find-symbol some-symbol-name)) 42)

Upvotes: 0

Vatine
Vatine

Reputation: 21258

If you absolutely want to do this, with global variables, I suspect that SET and SYMBOL-VALUE (and using symbols instead of strings) might do the trick. It definitely falls in the "hm, yes, you can do it that way, but I am not convinced it's the best way" territory, though.

However, you are most probably better off either using a hash-table or (skipping storage completely, if there's no need to mutate what A1 means further down the line) a function that parses the letter and digit apart and calculates the relevant value.

Upvotes: 0

Daniel Dickison
Daniel Dickison

Reputation: 21882

First of all -- are you sure you need to do this?

Now, with that out of the way --

(defvar *symbol-name* "zap")
(let ((symbol (intern *symbol-name*)))
  (proclaim `(special ,symbol))
  (setf (symbol-value symbol) 100))
(print |zap|)

Note that |zap| will normally need to be quoted with pipes, because intern is case-sensitive, while the default readtable upcases symbols by default. So if you don't quote, as in (print zap), that is interpreted as (PRINT ZAP), with the wrong case for zap. Alternatively, you can upcase the interned symbol, with (intern (string-upcase *symbol-name*)).


Update after seeing what you're actually trying to do.

You definitely don't want to be defining global variables for that. A data structure that maps keys (A1...H4, etc) to numbers is what you want. In this case, your keys can be symbols or strings. And the data structure could be a hashtable, a plist or alist (among other choices). For example, a string-keyed hashtable would look like:

(defvar *table* (make-hash-table :test #'equalp))
(setf (gethash "A1" *table*) 42)
(print (gethash "A1" *table*)) ==>  prints 42

Upvotes: 1

Xach
Xach

Reputation: 11854

It's usually better to use a hash table for that purpose.

Upvotes: 1

Related Questions