Ich habe ein Projekt mit leiningen namens Techne eingerichtet. Ich habe ein Modul namens scrub mit einem Typ namens Scrub und einer Funktion namens foo erstellt.Wie verwenden Sie einen Typ außerhalb seines eigenen Namensraums in clojure?
Techne/scrub.clj:
(ns techne.scrub)
(deftype Scrub [state]
Object
(toString [this]
(str "SCRUB: " state)))
(defn foo
[item]
(Scrub. "foo")
"bar")
Techne/scrub_test.clj:
(ns techne.scrub-test
(:use [techne.scrub] :reload-all)
(:use [clojure.test]))
(deftest test-foo
(is (= "bar" (foo "foo"))))
(deftest test-scrub
(is (= (Scrub. :a) (Scrub. :a))))
Wenn ich den Test ausführen, bekomme ich die Fehlermeldung:
Exception in thread "main" java.lang.IllegalArgumentException: Unable to resolve classname: Scrub (scrub_test.clj:11)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:5376)
at clojure.lang.Compiler.analyze(Compiler.java:5190)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:5357)
Wenn ich Test-Scrub entfernen alles funktioniert gut. Warum: Verwenden Sie techne.scrub 'importieren' die Funktionsdefinitionen, aber nicht die Typdefinitionen? Wie referenziere ich die Typdefinitionen?
Ich benutze immer Konstruktorfunktionen aus diesem Grund und für die Validierung. –
Ja, wir haben herausgefunden, dass es hilfreich ist, den Defrecord zu erweitern, um Konstruktorfunktionen automatisch mit Feldvalidierung, pprint Unterstützung zu einem eval-fähigen Formular usw. hinzuzufügen. –
Beachten Sie, dass diese Antwort vor Clojure 1.4 liegt. Seit 1.4 wird ein positioneller (-> Scrub) und map (map-> Scrub) -Konstruktor automatisch durch Defrecord erzeugt. Dies ist die bevorzugte Methode der Konstruktion und erfordert nur, dass Sie diese Funktionen in Ihren Namespace verweisen - Sie müssen die Klasse nicht importieren. –