Câu trả lời:
Đánh giá một chuỗi mã elisp là một quá trình gồm hai giai đoạn: bạn cần phân tích chuỗi bằng cách sử dụng read-from-string
và sau đó đánh giá biểu thức Lisp kết quả với eval
.
(defun my-eval-string (string)
"Evaluate elisp code stored in a string."
(eval (car (read-from-string string))))
Bây giờ (my-eval-string "(+ 1 2)")
đánh giá để 3
.
Chỉnh sửa:
Như @lunaryorn đã chỉ ra , chỉ read-from-string
đọc biểu thức đầu tiên , vì vậy điều này sẽ tốt hơn:
(defun my-eval-string (string)
(eval (car (read-from-string (format "(progn %s)" string)))))
Chỉnh sửa 2:
Để đánh giá mã elisp cho các tác dụng phụ, người ta cũng có thể sử dụng with-temp-buffer
và eval-buffer
( eval-buffer
luôn trả về 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
ít hơn lý tưởng bởi vì nó sẽ gây rối với tất cả các cuộc gọi liên quan đến bộ đệm, ví dụ: buffer-file-name
...
Câu trả lời của Constantine là ổn.
Chỉ để cung cấp một sửa đổi nhỏ:
(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)")
Mẫu cuối cùng trả về danh sách (1 2 3 4)
.
(calc-eval "1 - 2 + 3")
phù hợp với ví dụ python của bạn tốt hơn ngay cả khi điều này không hợp lệ. Nếu bạn chưa yêu cầucalc
gói bạn cần tải trước đó(require 'calc)
. (Tôi biết rằng điều này không trả lời câu hỏi của bạn. Do đó, nó được coi là bình luận.)