Wie kann man den in einem String enthaltenen Elisp-Code auswerten?
21
Die Frage sagt eigentlich schon alles: Ich habe einen String, der den Quellcode für einen gültigen Elisp-Ausdruck enthält, und ich würde ihn gerne auswerten.
(In Python wird der Ausdruck beispielsweise eval("1 - 2 + 3")zu 2 ausgewertet.)
Beachten Sie, dass (calc-eval "1 - 2 + 3")Ihr Python-Beispiel besser passt, auch wenn dies kein gültiges elisp ist. Wenn Sie das calcPaket noch nicht benötigen , müssen Sie es vorher mit laden (require 'calc). (Ich weiß, dass dies Ihre Frage nicht beantwortet. Daher wird es als Kommentar formuliert.)
Tobias
Antworten:
24
Das Auswerten einer Zeichenfolge aus Elisp-Code erfolgt in zwei Schritten: Sie müssen die Zeichenfolge mit analysieren read-from-stringund dann den resultierenden Lisp-Ausdruck mit auswerten eval.
(defun my-eval-string (string)"Evaluate elisp code stored in a string."(eval (car(read-from-string string))))
Jetzt (my-eval-string "(+ 1 2)")auswertet zu 3.
Bearbeiten:
Liest , wie von @lunaryorn hervorgehoben , read-from-stringnur den ersten Ausdruck , daher sollte dies besser sein:
Um den Elisp-Code auf Nebenwirkungen zu untersuchen, kann man auch with-temp-bufferund verwenden eval-buffer( eval-bufferimmer zurück nil).
(defun my-eval-string-for-side-effects (string)"Evaluate a string of elisp code for side effects."(with-temp-buffer
(insert string)(eval-buffer)))(my-eval-string-for-side-effects "(message \"hello!\")")
with-temp-bufferist weniger als ideal, weil es mit allen pufferbezogenen Anrufen durcheinander kommt, zB buffer-file-name...
Ha-Duong Nguyen
5
Die Antwort von Konstantin ist in Ordnung.
Nur um eine kleine Änderung vorzusehen:
(defun my-eval-string (str)"Read and evaluate all forms in str.
Return the results of all forms as a list."(let((next 0)
ret)(condition-case err
(while t(setq ret (cons(funcall (lambda(ret)(setq next (cdr ret))(eval (car ret)))(read-from-string str next))
ret)))(end-of-file))(nreverse ret)))(my-eval-string "1 2 3 (+ 3 1)")
Das letzte Formular gibt die Liste zurück (1 2 3 4).
(calc-eval "1 - 2 + 3")
Ihr Python-Beispiel besser passt, auch wenn dies kein gültiges elisp ist. Wenn Sie dascalc
Paket noch nicht benötigen , müssen Sie es vorher mit laden(require 'calc)
. (Ich weiß, dass dies Ihre Frage nicht beantwortet. Daher wird es als Kommentar formuliert.)Antworten:
Das Auswerten einer Zeichenfolge aus Elisp-Code erfolgt in zwei Schritten: Sie müssen die Zeichenfolge mit analysieren
read-from-string
und dann den resultierenden Lisp-Ausdruck mit auswerteneval
.Jetzt
(my-eval-string "(+ 1 2)")
auswertet zu3
.Bearbeiten:
Liest , wie von @lunaryorn hervorgehoben ,
read-from-string
nur den ersten Ausdruck , daher sollte dies besser sein:Bearbeiten 2:
Um den Elisp-Code auf Nebenwirkungen zu untersuchen, kann man auch
with-temp-buffer
und verwendeneval-buffer
(eval-buffer
immer zurücknil
).quelle
with-temp-buffer
ist weniger als ideal, weil es mit allen pufferbezogenen Anrufen durcheinander kommt, zBbuffer-file-name
...Die Antwort von Konstantin ist in Ordnung.
Nur um eine kleine Änderung vorzusehen:
Das letzte Formular gibt die Liste zurück
(1 2 3 4)
.quelle