2013-05-31 3 views
2

Clojure에서 심볼을 새 데이터 구조로 리 바인드하는 방법은 무엇입니까? 예를 들면 : 나는 데이터 파일에 의존하는 웹 서비스를 가지고 있기 때문에Clojure : 새 데이터 구조에 심볼 리 바인딩

(def hash-map-one {:a "foo" :b "bar"}) 
(def hash-map-two {:c "gaz" :d "waka"}) 

;; right here make hash-map-one equal to hash-map-two very quickly 
;; if this were python I would say hash-map-one = hash-map-two 

약간의 동기 부여, 내가이 일을하고있어, 그 데이터 파일이 다운 타임없이, 어느 시점에서 내가 필요, 업데이트됩니다, 새 데이터로 "전환"하십시오.

미리 감사드립니다. 가장 의미가 있습니다 원자를 사용하여, 사용 사례 감안할 때

+0

부수적으로 기호는 Clojure의 저장 위치가 아닙니다. 여기에있는 해시 맵은 Vars에 저장됩니다. 이것들은 상징적 인 이름을 가지고 있지만, 다른 네임 스페이스의 다른 Vars를 해결할 수 있습니다. (이것은 별칭 때문에 네임 스페이스가있는 기호에도 적용됩니다.) –

답변

5

:

(def data (atom {:map 'of :initial "data"})) 

(reset! data {:map 'of :new "data"}) 

당신이 바르를 사용하는 것을 선호 어떤 이유로, 당신이 새로운 가치로 전환하는 alter-var-root를 사용할 수있는 경우

. intern을 사용할 수도 있지만, alter-var-root의 원 자성 보증을 잃을 수도 있지만 (docstring 및 this answer 참조, 설명 : defintern에도 동일하게 적용됩니다).

REPL에서 def을 사용하여 기존 Vars를 리바 인딩하는 것은 완벽하지만 괜찮습니다 (일부 특별한 예외는 Clojure 구현에서 발견되는 매우 특별한 경우입니다). 무엇보다도 def은 최상위 형식에서만 사용되어 즉시 실행됩니다. 즉, 최상위 양식 자체 또는 let과 같은 최상위 양식의 본문 일부 여야합니다. 그렇지 않으면 weirdness ensues.

+0

굉장하고, 훌륭한 답변을 주셔서 감사합니다. 이봐 요, 저는 그냥 repl에서 놀고 있었고 이렇게했을 때 이마를 때렸습니다 :'user => (def x {: a 1 : b 2}) # 'user/x user => ([y { : c 3 : d 4}] (dosync (def xy)))'이것이 전역 변수가 될 경우 (jetty의 서버 시작시 생성됨), 괜찮습니까? 아니면 함정이 있습니까? –

+0

또한 이것이 부두와 같은 스레드 웹 서버에 있다면, 나는 네가 작동 할 것이라고보고, 간단한 def 문을 쓸 것인가? –

+1

몇 가지 추가 정보를 추가하기 위해 지금 답변을 편집했습니다. 'def'는 함수 내부에서 사용하기에 적합하지 않습니다 (그 이유에 대한 설명은 대답 끝의 링크를보십시오). 대신에'intern'를 사용하십시오. 덧붙여 말하자면 첫 번째 주석의'dosync'는 아무 것도하지 않습니다. –

관련 문제