2014-10-04 1 views
2

원자로 뒷받침 된 클로저 스크립트에 concept of a Cursor을 빌드하려고합니다. 커서는 변경 불가능한 중첩 된 관련 데이터 구조를 편집하기위한 재귀 지퍼와 같은 메커니즘입니다.프로토콜로 어려움을 겪고있는 Clojure 초보자

저는 Clojure에서 매우 초보자입니다. 제 실수를 발견하도록 도와 줄 수 있습니까?

(defprotocol Cursor 
    (refine [this path]) 
    (set [this value]) 
    (value [this])) 

(defn- build-cursor* [state-atom paths] 
    (reify Cursor 
    (set [this value] (swap! state-atom (assoc-in @state-atom paths value))) 
    (refine [this path] (build-cursor* state-atom (conj paths path))) 
    (value [this] (get-in @state-atom paths)))) 

(defn build-cursor [state-atom] 
    (build-cursor* state-atom [])) 

(comment 
    (def s (atom {:a 42})) 
    (def c (build-cursor s)) 
    (assert (= (value c) {:a 42})) 
    (set c {:a 43}) ;; WARNING: Wrong number of args (2) passed to quiescent-json-editor.core/set at line 1 <cljs repl> 
    (assert (= (value c) {:a 43})) 
    (def ca (refine c :a)) ;; WARNING: Wrong number of args (2) passed to quiescent-json-editor.core/refine at line 1 <cljs repl> 

    (assert (= (value ca) 43)) 
    (set ca 44) 
    (assert (= (value ca) 43)) 


) 

답변

1

나는 Clojure도 처음이지만 두 가지 문제점을 발견했다.

먼저 set 메서드는 핵심 라이브러리 함수와 충돌합니다 (Cursor 프로토콜에도 있음). 디버깅을 위해이 문제를 피하기 위해 밑줄 접두사를 추가했습니다.

둘째, 루트 커서에서 _set을 호출하면 값이 손상되는 것 같습니다. 그 _setcond에 대한 이유가 그래서 ...

(assoc-in {} [] {:a 7}) 
; {nil {:a 7}} 

: 나는 assoc-in 빈 경로 [] 당신이 예상하는 방식을 처리하지 않는 것을 발견했다. ASSOC - 빈 경로에 대한

(ns cursory) 

(defprotocol Cursor 
    (_path [this]) 
    (_root [this]) 
    (_refine [this path]) 
    (_set [this value]) 
    (_value [this])) 

(defn- build-cursor* [state-atom paths] 
    (reify Cursor 
    (_path [this] paths) 
    (_root [this] @state-atom) 
    (_set [this value] (cond 
         (empty? paths) (reset! state-atom value) 
         :else (assoc-in @state-atom paths value))) 
    (_refine [this path] (build-cursor* state-atom (conj paths path))) 
    (_value [this] (get-in @state-atom paths)))) 

(defn build-cursor [state-atom] 
    (build-cursor* state-atom [])) 

(comment 
    (def s (atom {:a 42, :b 84})) 
    (def c (build-cursor s)) 
    (_set c {:a 44, :b 88}) 
    (_root c) 
    (_path c) 
    (_value c) 
    (def ca (_refine c :a)) 
    (_path ca) 
    (_value ca) 
    (_set ca 42) 
    (get-in {:a 1 :b 2} []) 
    (assoc-in {} [:a :b] 7) 
    (assoc-in {} [] {:a 7}) 
    (empty? []) 
) 
+0

JIRA 문제 : 다음은

내 테스트 코드입니다 http://dev.clojure.org/jira/browse/CLJ-1520 – lnmx

관련 문제