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-stringvà 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-buffervà eval-buffer( eval-bufferluô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ầucalcgó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.)