3

オーバーロードされたプロトコル定義の一部は次のとおりです。

(defprotocol ClientProtocol
  (create-edge
    [this outV label inV] 
    [this outV label inV data])

そして、ここにその実装の一部があります:

(ns bulbs.neo4jserver.client
  (:use [bulbs.base.client :only [ClientProtocol]]))

(deftype Neo4jClient [ns config]
  ClientProtocol

  (create-edge
    [this outV label inV data]
    (let [inV-uri (utils/normalize-uri (build-path neo4j-uri vertex-path inV))
          path (build-path vertex-path, outV, "relationships")
          params {:to inV-uri, :type label, :data (first data)}]
      (post config path params)))

  (create-edge
    [this outV label inV]
    ;; it doesn't like this call...
    (create-edge this outV label inV nil)) 

2番目のメソッドが最初のメソッドを呼び出そうとすると、このエラーが発生します。

java.lang.RuntimeException: Unable to resolve symbol: create-edge in this context

SLIMEで最初の関数を使用してコンパイルし、次に戻って2番目の関数を追加したときに、両方の定義が機能していました。

しかし、プロトコル定義を別のファイルに移動してすべてを再コンパイルしようとすると、おそらく最初のメソッドがまだ定義されていないために、2番目のメソッドが最初のメソッドを呼び出そうとするとエラーがスローされます。

Clojureのreifyドキュメントには次のコメントがあります:

プロトコル/インターフェースでメソッドがオーバーロードされている場合は、複数の独立したメソッド定義を指定する必要があります。

http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/reify

これらは独立した定義ではないと思います。

これにアプローチする正しい方法は何ですか?

4

3 に答える 3

3

名前空間の宣言が間違っています。

(ns bulbs.neo4jserver.client
  (:use [bulbs.base.client :only [ClientProtocol]]))

プロトコル関数は通常のClojure関数であり、そのように扱う必要があります。したがって、それらを:only句に含める必要があります。

(ns bulbs.neo4jserver.client
  (:use [bulbs.base.client :only [create-edge ClientProtocol]]))
于 2012-05-21T06:15:12.367 に答える
2

これは、clojure1.4.0で機能する簡略化された例です。

(ns hello.core)
(defprotocol ClientProtocol
 (create-edge
    [this outV label inV] 
    [this outV label inV data]))

(deftype Neo4jClient []
  ClientProtocol

 (create-edge
   [this outV label inV data]
    4)

  (create-edge
    [this outV label inV]
    (create-edge this outV label inV nil)))

hello.core> (create-edge (Neo4jClient.) 2 3 4)
4

hello.core> (create-edge (Neo4jClient.) 2 3 4 5)
4

これは相互再帰的な例です(基本ケースなし)

(deftype Neo4jClient []
  ClientProtocol

  (create-edge
    [this outV label inV data]
    (println "OMG im in a looooooop...")
    (create-edge this 1 2 3))

  (create-edge
    [this outV label inV]
    (println "AHHH im in a looooooop...")
    (create-edge this 1 2 3 4)))


hello.core> (create-edge (Neo4jClient.) 1 2 3 4)
OMG im in a looooooop...
AHHH im in a looooooop...
OMG im in a looooooop...
AHHH im in a looooooop...
OMG im in a looooooop...
AHHH im in a looooooop...
OMG im in a looooooop...
AHHH im in a looooooop...
于 2012-05-18T00:38:42.980 に答える
0

ここで行っていることは問題なく機能します。

この例を考えてみましょう。

(defprotocol ClientProtocol
  (create-edge
    [this outV label inV]
    [this outV label inV data]))

(deftype SampleClient []
  ClientProtocol

  (create-edge
    [this outV label inV]
      (create-edge this outV label inV {}))

  (create-edge
    [this outV label inV data]
      {:action :create-edge :this this :outV outV :label label :inV inV :data data}))

実行時の動作は予想どおりです。

; => (create-edge (SampleClient.) 1 2 3)
{:action :create-edge, :this #<SampleClient user.SampleClient@63a2cc03>,
 :outV 1, :label 2, :inV 3, :data {}}
; => (create-edge (SampleClient.) 1 2 3 4)
{:action :create-edge, :this #<SampleClient user.SampleClient@7144c1a4>,
 :outV 1, :label 2, :inV 3, :data 4}
于 2012-05-18T18:59:47.063 に答える