Clojure Protocol Implementation not Found for Record Type in other namespace -
we having few issues records , protocols in different namespaces.
we have protocol in namespace foo.proto.
(ns foo.proto) (defprotocol proto (do-stuff [this x y]))
i have record recorda in namespace foo.record:
(ns foo.record (:require [foo.proto :as proto])) (defrecord recorda [bar]) ;; recorda implements protocol: (extend-type recorda proto/proto (do-stuff [this x y] (* x y (:bar this))))
this works fine long in repl. if on otherhand make uberjar , run code get:
no implementation of method: :do-stuff of protocol: #'foo.proto/proto found class
if on other hand implement protocol in type declaration so:
(defrecord recorda [bar] proto/proto (do-stuff [this x y] (* x y (:bar this))))
we no longer error (which took time figure out). if move declaration of proto same ns recorda not error either.
my questions:
what difference between implementing in declaration , in extend-type or extend-protocol?
why work if move record , protocol declarations same ns?
thanks
the issue may in how including record , protocol within file using them. following works me:
record.clj
(ns testclojure.record (:require [testclojure.proto :as proto])) (defrecord recorda [bar]) (extend-type recorda proto/proto (do-stuff [this x y] (* x y (:bar this))))
proto.clj
(ns testclojure.proto) (defprotocol proto (do-stuff [this x y]))
core.clj
(ns testclojure.core (:require [testclojure.record :refer [->recorda]] [testclojure.proto :refer :all]) (:gen-class)) (defn -main [& args] (-> (->recorda 2) (do-stuff 2 6) (println)))
after lein uberjar
, running jar directly, correct answer of 24.
as why works different combinations of namespaces , extending, defrecord
creates java class while extend-type
creates entry in :impls
collection of protocol.
Comments
Post a Comment