文字列に含まれるElispコードを評価する方法は?


21

質問はほとんどすべてを言っています:有効なElisp式のソースコードを含む文字列があり、それを評価したいと思います。

(たとえば、Pythonでは、式eval("1 - 2 + 3")は2に評価されます。)


2
(calc-eval "1 - 2 + 3")これが有効なelispでなくても、Pythonの例によりよく適合することに注意してください。calcパッケージをまだ必要としない場合は、前にパッケージをロードする必要があります(require 'calc)。(これはあなたの質問に答えないことを知っています。したがって、コメントとして定式化されます。)
トバイアス

回答:


24

elispコードの文字列の評価は2段階のプロセスです。文字列を使用して解析し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

編集:

で指摘したように@lunaryornread-from-string 唯一の最初の式を読み取って、これは良いはずですので、:

(defun my-eval-string (string)
  (eval (car (read-from-string (format "(progn %s)" string)))))

編集2:

elispコードの副作用を評価するにはwith-temp-buffer、and eval-buffereval-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)")

最後のフォームはリストを返します(1 2 3 4)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.