2017-10-16 5 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とは言えません。私がやりたいことがたくさんあるように思えるのは、Ubergraphに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がこれを許可したことを知っていましたが、私はこの問題に関連してそれを考えていませんでした。これは、瞬時に私の現在の問題の多くを、理想的なコード量で解決します。しかし、私はUbergraphに 'assoc'を試みましたが、うまくいきませんでした。だから、私は今質問を開いたままにしておきます。 (Ubergraphに任意のデータを追加することは実際には私が今必要な主な実用的な理由です) –

+0

うーん、Ubergraphも[case statements](https://github.com/Engelberg/ubergraph/blob/320e284a6de6adb241df5dfeb9fd6383caea659c/src/ ubergraph/core.clj#L214)を使用して、任意のキーへのアソシエーションを防ぎます。 –

関連する問題