Stuart Sierra의 의견 (clojure.core/intern
언급)을 고려하여 업데이트되었습니다.
여기에 eval
을 사용하면 괜찮 았지만 Vars가 이미 존재하는지 여부에 관계없이 필요하지 않다는 것을 아는 것은 흥미로울 수 있습니다. 사실, 그들이 존재하는 것으로 알려져 있다면, 나는 아래의 alter-var-root
솔루션이 더 깨끗하다고 생각합니다; 그것들이 존재하지 않는다면, 나는 대안적인 제안을 훨씬 더 깨끗하게 주장하지 않을 것이지만, 가장 짧은 코드 (함수 정의를 위해 3 줄의 오버 헤드를 무시한다면)를 게시하는 것처럼 보인다. 그래서 나는 단지 포스트 할 것이다. 그것을 고려하십시오.
var에 존재하는 것으로 알려져 경우
(alter-var-root (resolve (symbol "foo")) (constantly new-value))
그래서 당신이 할 수있는 동일한 값이 모든 바르에 사용되는 있었다면
(dorun
(map #(-> %1 symbol resolve (alter-var-root %2))
["x" "y" "z"]
[value-for-x value-for-y value-for z]))
(당신이
(repeat value)
을 사용할 수 있습니다 마지막 인수를 매핑하거나 그냥 익명 함수에 넣으십시오.바르가 생성해야 할 수 있습니다)
, 당신은 실제로 나는 반드시이 eval
청소기보다라고 주장하지만, 어쨌든 않을 것이다, 다시 한번 (이 작업을 수행하는 함수를 작성할 수 있습니다 - 단지에 대한 그것의 관심) : var에가 밝혀지면 이미 주어진 네임 스페이스에 지정된 이름에 구금 된 것을
(defn create-var
;; I used clojure.lang.Var/intern in the original answer,
;; but as Stuart Sierra has pointed out in a comment,
;; a Clojure built-in is available to accomplish the same
;; thing
([sym] (intern *ns* sym))
([sym val] (intern *ns* sym val)))
주, 다음이 하나의 인수 경우 아무것도 변경하거나 단지에 바르 재설정 두 가지 주장에 새로운 가치가 주어진다. 목록의 모든 항목을 평가할 수있는 일반 함수 호출에 대한
user> (create-var 'bar (fn [_] :bar))
#'user/bar
user> (bar :foo)
:bar
user> (create-var 'baz)
#'user/baz
user> baz
; Evaluation aborted. ; java.lang.IllegalStateException:
; Var user/baz is unbound.
; It does exist, though!
;; if you really wanted to do things like this, you'd
;; actually use the clojure.contrib.with-ns/with-ns macro
user> (binding [*ns* (the-ns 'quux)]
(create-var 'foobar 5))
#'quux/foobar
user> quux/foobar
5
가장 간결하고 직관적 인 (가능한?) 대답. 나는 당신에게 눈금을줬고 sepp2k가 그것을 잃어 버리는 것에 대해 화를 내지 않기를 바란다. 감사! –