0

I want to do this.

(let ((myvar "my/variable")
      (myval "Some Value"))
  (setq myvar myval))

The manual method is:

(setq "my/variable" "Some Value")

Here is the full code: As you can see the values are shown in the messages area but they are not set as variables.

(define-error 'my-own-errors   "My Errors")
(define-error 'wrong-arguments "Wrong Arguments" 'my-own-errors)
(define-error 'file-missing    "File Missing"    'my-own-errors)
(define-error 'unknown         "Unknown Error"   'my-own-errors)

(defun my/map--nested-alist (callback NLIST)
  "Call CALLBACK with key value pairs."
  (cond ((stringp NLIST)
         (unless (file-exists-p NLIST)
           (error (signal 'file-missing '(NLIST "was not found.")))))
        ((not (listp NLIST))
         (error (signal 'wrong-arguments '(NLIST "is not a list"))))
        ((listp NLIST) ; Ideally check the list for (dot . notation)
         t)
        (t
         (error (signal 'unknown '(NLIST "was not found.")))))
  (dotimes (x (length NLIST))
    (let* ((group (nth x NLIST))
           (cl (nth 0 (cdr group))) ; cons or list
           (key (car group))
           ;; if list use nth if cons (foo . bar) use cdr
           (val1 (if (consp cl)
                     (car cl)
                   (nth 0 cl)))
           ;; TODO: I could not figure out how to account for cons (dot . notation)
           ;; for now don’t use a '.' in the file, will look at it later.
           (val2 (if (consp cl)
                     (nth 1 cl)
                   (cdr cl))))
      (funcall callback
               `(:key ,key :val1 ,val1 :val2 ,val2)))))

(my/map--nested-alist (lambda (x)
                        (let* ((key   (format "%s" (plist-get x :key)))
                               (myvar (format "%s" (plist-get x :val1))))
                          (progn
                            (message "key is: %s val: %s" key myvar)
                            (setq key myvar))))
                      (with-temp-buffer (insert-file-contents "~/.config/emacs/.data/fakefile")
                                        (read (buffer-string))))

Here is the file in ~/.config/emacs/.data/fakefile

(("my/website"  ("~/Documents/website"  "Website stuff Comment"))
 ("my/journals" ("~/Documents/journals"                     nil))
 ("my/example"  ("~/Documents/example"        "Example Comment")))
5
  • emacs.stackexchange.com/tags/elisp/info
    – Drew
    Commented Feb 19, 2023 at 23:56
  • @Drew let* don't work.
    – ritchie
    Commented Feb 19, 2023 at 23:59
  • The variable needs to be a symbol, not a string: 'my/variable, not "my/variable".
    – Drew
    Commented Feb 20, 2023 at 0:01
  • @Drew that don't work (let* ((myvar 'my/variable).....
    – ritchie
    Commented Feb 20, 2023 at 0:04
  • 2
    See Variables in the Emacs Lisp reference manual, but you might profit from a basic Lisp introduction (I like "The Little Lisper" by Friedman and Felleisen).
    – NickD
    Commented Feb 20, 2023 at 13:06

2 Answers 2

2

intern turns a string into a symbol, then you can use set on that symbol:

(set (intern "var") "some value")
var
⇒ "some value"

or

(setq varname "var")
(set (intern varname) "some value")
var
⇒ "some value"

(setq NAME VALUE) is a contraction of (set 'NAME VALUE) (notice the quote, hence the "q"). setq suppresses the evaluation of its first argument (think about it, most Elisp function would expand NAME to its value as a variable, e.g. (concat var "some string"). In fact, setq isn't a function, it is a special form). You don't need this when you invoke intern, that's why you use set.

1

The variable needs to be a symbol, not a string: my/variable, not "my/variable".

(let ((myvar 'my/variable)
      (myval "Some Value"))
  (set myvar myval)
  (message "MYVAR: %S" myvar))

Of course, if you want to change a global (i.e., dynamically bound) variable named my/variable then you need to declare it as such:

(defvar my/variable "Some Value")

Or

(defvar my/variable)

(let ((myval "Some Value"))
  (setq my/variable myval))

Or even just this (not inside a let):

(setq my/variable "Some Value")

It all depends on what you want to do. What that is isn't clear.

8
  • That does not work.
    – ritchie
    Commented Feb 20, 2023 at 0:07
  • @ritchie It does work, so... please update your question to show precisely what you're doing (including precisely how you're testing it).
    – phils
    Commented Feb 20, 2023 at 3:07
  • 1
    It looks like you're still using setq rather than set as Drew showed you.
    – phils
    Commented Feb 20, 2023 at 9:44
  • 1
    The answer to your question is nevertheless to use set. With a variable VAR set to a symbol value, (set VAR VALUE) will assign VALUE to that symbol. Which is what you asked how to do. Anything else is just debugging (in your case "my/website" is a string and you need to use a symbol -- Drew also pointed this out in the answer).
    – phils
    Commented Feb 20, 2023 at 21:28
  • 1
    Sure (and that's a very good thing to know), but you can also not use a string in the first place if you don't need to be doing that. Is there anywhere that you need the value "my/website" as a string? If not, make it a symbol and then you won't need to intern it.
    – phils
    Commented Feb 20, 2023 at 21:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.