2017-10-16 14 views
2

프로토콜을 기존 유형에서 "상속"하는 새 레코드를 정의하려면 어떻게해야합니까?프로토콜 방식을 기존 유형으로 전달하는 방법은 무엇입니까?

이 질문을 명확하게하기 위해 Ubergraph을 확장하여 설명 하겠지만 Ubergraph는 단지 예일뿐입니다. Ubergraph에서 작동하는 솔루션이 아니라 일반적인 솔루션을 찾고 있습니다. Ubergraph에 글로벌 속성 인 graph-name을 추가하고 싶다고 가정 해 보겠습니다. 이상적으로, 나는 이런 식으로 뭔가를 할 수 :

(defrecord named-ubergraph [g graph-name]) 

(extend-type named-ubergraph 
    (all-the-protocols-supported-by ubergraph.core.Ubergraph) 
    (call-the-same-functions-replacing-first-argument-with '(this g)) 
나는 Ubergraph 소스 코드를보고 수동으로 모든 전송 기능을 쓸 수 물론

하지만 as you can see here, Ubergraph 만족 많은 프로토콜과 많은 프로토콜 방법.

너무 많은 상용구 코드를 작성하면 Clojurely 소리가 나지 않으며, 내가하고 싶은 일은 우거버 그래프에 1 비트의 데이터를 추가하는 것입니다. 더 좋은 방법이 있니?

내가 잘못 생각하는 경우 언제든지 질문을 재 개념화하십시오.

답변

1

extend-type은 주어진 프로토콜에 기존 유형을 확장합니다. 제대로 이해하면 상속을 받기 위해 기존 레코드를 확장하고 싶습니다. AFAIK, 쉬운 방법이 없습니다. 그러나, 당신이 원하는 모든 다른 필드를 추가하는 경우, 당신이 할 수있는 기존 레코드 인스턴스에 쉽게 assoc 추가 필드 :

UPDATE
(defprotocol Cost 
    (cost [this price-list])) 

(defrecord Car [name speed] 
    Cost 
    (cost [this price-list] (price-list (:name this)))) 

(def my-car (->Car "bmw" 200)) 
(def price-list {"bmw" 100000}) 

(cost my-car price-list) 
;;=> 100000 

(-> my-car 
    (assoc :color "blue") 
    (cost price-list)) 
;;=> 100000 

: 나는 또한 Clojure의 메일 링리스트에이 환상적인 토론을 발견했습니다 : defrecord와 "상속": https://groups.google.com/forum/#!topic/clojure/mr-o9sRyiZ0

+0

레코드에 'assoc'-ing하는 것은 좋은 통찰력입니다! 나는 Clojure가 이것을 허용했다는 것을 알았지 만, 나는이 문제와 관련하여 그것을 생각하지 않았다. 이제는 이상적인 코드의 양으로 즉각적인 해결로 많은 문제점을 해결할 수 있습니다 : none! 그러나 Ubergraph에'assoc'-ing을 시도했지만 작동하지 않습니다. 그래서 지금 질문을 공개하고 있습니다. (Ubergraph에 임의의 데이터를 추가하는 것은 사실 현재 실제로 필요한 주요 실용적인 이유입니다.) –

+0

음, Ubergraph도 [case statements] (https://github.com/Engelberg/ubergraph/blob/320e284a6de6adb241df5dfeb9fd6383caea659c/src/)를 가지고 있습니다. ubergraph/core.clj # L214)을 사용하면 임의의 키에 대해 'assoc'을 방지 할 수 있습니다. –