मुझे क्लोजर रिकॉर्ड्स से संबंधित प्रतीत होता है कि थोड़ा आश्चर्यजनक व्यवहार है।रिकॉर्ड्स, प्रोटोकॉल और संकलन से संबंधित आश्चर्यजनक व्यवहार
एक नाम स्थान एक रिकॉर्ड प्रकार परिभाषित करता है::
(ns defrecordissue.arecord) (defrecord ARecord [])
एक और नाम स्थान एक प्रोटोकॉल को परिभाषित करता है, और रिकॉर्ड टाइप 1 में परिभाषित करने के लिए इसे फैली
सेटअप इस प्रकार है:
(ns defrecordissue.aprotocol (:require [defrecordissue.arecord]) (:import [defrecordissue.arecord ARecord])) (defprotocol AProtocol (afn [this])) (extend-protocol AProtocol ARecord (afn [this] 42))
एक तीसरा नामस्थान रिकॉर्ड का एक उदाहरण बनाता है और रिकॉर्ड पर प्रोटोकॉल फ़ंक्शन को आमंत्रित करता है।
Exception in thread "main" java.lang.IllegalArgumentException: No implementation of method: :afn of protocol: #'defrecordissue.aprotocol/AProtocol found for class: defrecordissue.arecord.ARecord, compiling:(aot1.clj:5:1) at clojure.lang.Compiler$InvokeExpr.eval(Compiler.java:3463) at clojure.lang.Compiler.compile1(Compiler.java:7153) at clojure.lang.Compiler.compile(Compiler.java:7219) at clojure.lang.RT.compile(RT.java:398) at clojure.lang.RT.load(RT.java:438) at clojure.lang.RT.load(RT.java:411) at clojure.core$load$fn__5018.invoke(core.clj:5530) at clojure.core$load.doInvoke(core.clj:5529) at clojure.lang.RestFn.invoke(RestFn.java:408) at clojure.core$load_one.invoke(core.clj:5336) at clojure.core$compile$fn__5023.invoke(core.clj:5541) at clojure.core$compile.invoke(core.clj:5540) at user$eval7.invoke(NO_SOURCE_FILE:1) at clojure.lang.Compiler.eval(Compiler.java:6619) at clojure.lang.Compiler.eval(Compiler.java:6609) at clojure.lang.Compiler.eval(Compiler.java:6582) at clojure.core$eval.invoke(core.clj:2852) at clojure.main$eval_opt.invoke(main.clj:308) at clojure.main$initialize.invoke(main.clj:327) at clojure.main$null_opt.invoke(main.clj:362) at clojure.main$main.doInvoke(main.clj:440) at clojure.lang.RestFn.invoke(RestFn.java:421) at clojure.lang.Var.invoke(Var.java:419) at clojure.lang.AFn.applyToHelper(AFn.java:163) at clojure.lang.Var.applyTo(Var.java:532) at clojure.main.main(main.java:37) Caused by: java.lang.IllegalArgumentException: No implementation of method: :afn of protocol: #'defrecordissue.aprotocol/AProtocol found for class: defrecordissue.arecord.ARecord at clojure.core$_cache_protocol_fn.invoke(core_deftype.clj:541) at defrecordissue.aprotocol$fn__40$G__35__45.invoke(aprotocol.clj:5) at clojure.lang.AFn.applyToHelper(AFn.java:161) at clojure.lang.AFn.applyTo(AFn.java:151) at clojure.lang.Compiler$InvokeExpr.eval(Compiler.java:3458) ... 25 more
अगर मैं 3 बदल) रिकॉर्ड के निर्माण के लिए:
(ns defrecordissue.aot1 (:require [defrecordissue.aprotocol] [defrecordissue.arecord])) (defrecordissue.aprotocol/afn (defrecordissue.arecord/->ARecord))
जब defrecordissue.aot1 नाम स्थान मेरे मामले lein compile defrecordissue.aot1
का उपयोग करने में संकलित किया गया है,, संकलन निम्न अपवादों के साथ विफल रहता है कक्षा सीधे, जैसे:
(ns defrecordissue.aot2
(:require [defrecordissue.aprotocol]
[defrecordissue.arecord]))
(defrecordissue.aprotocol/afn (defrecordissue.arecord.ARecord.))
संकलन सफल होता है।
मेरा संदेह यह है कि यह किसी भी तरह http://dev.clojure.org/jira/browse/CLJ-371 से संबंधित है, लेकिन मुझे बिल्कुल ठीक नहीं हो रहा है।
मैं भी lein clean
बिना कि जोड़ना चाहिए, संकलन सफल होता है दूसरी बार के बाद से रिकॉर्ड के लिए एक वर्ग अब classpath पर उपलब्ध है। इसलिए, मैं एओटी-संकलन द्वारा रिकॉर्ड प्रकार को परिभाषित करने वाले नामस्थान द्वारा इस समस्या को हल कर सकता हूं। https://github.com/ragnard/defrecordissue
मैं इस व्यवहार क्यों दिखाई दे रहा है, और क्या यह से बचने के लिए सही तरीका है:
मुझे लगता है कि मुद्दे को दर्शाता है, के उपयोग के लिए README देख GitHub पर एक सरल leiningen प्रोजेक्ट बनाया?
अद्यतन
मैं GitHub रेपो के लिए एक नई शाखा जोड़ा बेहतर मुख्य मुद्दा illustrating: https://github.com/ragnard/defrecordissue/tree/more-realistic/
समस्या तब होती है, जहां (। यानी जो नाम स्थान में) रिकॉर्ड उदाहरण है की परवाह किए बिना का निर्माण किया।
अच्छा विचार, हालांकि एक ही अपवाद। मुझे लगता है कि 'defrecordissue.arecord' किसी भी मामले में पहले लोड किया जाएगा, क्योंकि इसे' defrecordissue.aprotocol' – Ragge
में भी आवश्यक है टिप्पणी से ऊपर एक और टिप्पणी से संबंधित था जो स्पष्ट रूप से हटा दिया गया था। – Ragge