Вопрос в значительной степени говорит сам за себя: у меня есть строка, содержащая исходный код для допустимого выражения Elisp, и я хотел бы оценить его.
(Например, в Python выражение eval("1 - 2 + 3")оценивается как 2.)
Обратите внимание, (calc-eval "1 - 2 + 3")лучше подходит для вашего примера с Python, даже если это недопустимый elisp. Если вам пока не требуется calcпакет, вам необходимо загрузить его до (require 'calc). (Я знаю, что это не отвечает на ваш вопрос. Следовательно, это сформулировано как комментарий.)
Тобиас
Ответы:
24
Оценка строки кода elisp - это двухэтапный процесс: вам нужно проанализировать строку, используя, read-from-stringа затем оценить полученное выражение Lisp с помощью eval.
(defun my-eval-string (string)"Evaluate elisp code stored in a string."(eval (car(read-from-string string))))
Теперь (my-eval-string "(+ 1 2)")оценивает 3.
Редактировать:
Как указывает @lunaryorn , read-from-stringчитает только первое выражение , так что это должно быть лучше:
Для оценки кода elisp для побочных эффектов можно также использовать with-temp-bufferи eval-buffer( eval-bufferвсегда возвращает 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-bufferменее чем идеален, потому что он испортит все вызовы, связанные с буфером, например buffer-file-name, ...
Ха-Дуонг Нгуен,
5
Ответ Константина в порядке.
Просто чтобы предоставить небольшую модификацию:
(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)")
(calc-eval "1 - 2 + 3")
лучше подходит для вашего примера с Python, даже если это недопустимый elisp. Если вам пока не требуетсяcalc
пакет, вам необходимо загрузить его до(require 'calc)
. (Я знаю, что это не отвечает на ваш вопрос. Следовательно, это сформулировано как комментарий.)Ответы:
Оценка строки кода elisp - это двухэтапный процесс: вам нужно проанализировать строку, используя,
read-from-string
а затем оценить полученное выражение Lisp с помощьюeval
.Теперь
(my-eval-string "(+ 1 2)")
оценивает3
.Редактировать:
Как указывает @lunaryorn ,
read-from-string
читает только первое выражение , так что это должно быть лучше:Изменить 2:
Для оценки кода elisp для побочных эффектов можно также использовать
with-temp-buffer
иeval-buffer
(eval-buffer
всегда возвращаетnil
).источник
with-temp-buffer
менее чем идеален, потому что он испортит все вызовы, связанные с буфером, напримерbuffer-file-name
, ...Ответ Константина в порядке.
Просто чтобы предоставить небольшую модификацию:
Последняя форма возвращает список
(1 2 3 4)
.источник