(def s "(- a b)"))
のような文字列があるとき, 実行時に決まる値で a や b を束縛して, この式を評価したいとする.
(let [a 4 b 3] (eval (read-string s)))
は
CompilerException java.lang.RuntimeException: Unable to resolve symbol: a in this context, compiling:(NO_SOURCE_PATH:2:1)
といった例外で失敗する.
引数に a や b を受け取る関数を eval に返させて, それを実行時に適用することで, 所望の動作を実現できる.
((eval (read-string (str "(fn [a b] " s ")"))) 4 3) ; -> 1
eval による関数の生成と, その適用を分けて書けば以下のようになる.
(let [f (eval (read-string (str "(fn [a b] " s ")")))]
(f 4 3))
; -> 1
参考: [Clojure Google Group 「(let [a 0] (eval 'a))」] (https://groups.google.com/forum/#!topic/clojure/eAo_vjQartU)
When given a string
(def s "(- a b"))
, I want to evaluate the expression with a and b binded with values determined at runtime.
(let [a 4 b 3] (eval (read-string s)))
fails with an exception like
CompilerException java.lang.RuntimeException: Unable to resolve symbol: a in this context, compiling:(NO_SOURCE_PATH:2:1)
You can do what you want to do with letting eval
return a function which receives a
and b
as arguments,
and applying the function at runtime.
((eval (read-string (str "(fn [a b] " s ")"))) 4 3) ; -> 1
You can write it with a generation of function and the application separated.
(let [f (eval (read-string (str "(fn [a b] " s ")")))]
(f 4 3))
; -> 1
reference: [Clojure Google Group: "(let [a 0] (eval 'a))"] (https://groups.google.com/forum/#!topic/clojure/eAo_vjQartU)