Mam projekt skonfigurowany z leiningen o nazwie techne. Stworzyłem moduł o nazwie scrub z typem zwanym Scrub i funkcją o nazwie foo.Jak używać typu spoza własnej przestrzeni nazw w 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))))
Kiedy wykonać test, pojawia się błąd:
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)
gdybym usuń test-scrub wszystko działa dobrze. Dlaczego: use techne.scrub "importuje" definicje funkcji, ale nie definicje typów? Jak odwołać się do definicji typów?
Zawsze używam funkcji konstruktora z tego powodu i do sprawdzania poprawności. –
Tak, uznaliśmy za pomocne przedłużenie defrecordu, aby automatycznie dodawać funkcje konstruktora z walidacją pól, obsługę pprint do formularza eval-able itd. –
Należy pamiętać, że ta odpowiedź poprzedza Clojure 1.4. Od wersji 1.4 konstruktor pozycyjny (-> Scrub) i map (map-> Scrub) zostanie automatycznie utworzony przez defrecord. Jest to preferowana metoda konstrukcji i wymaga tylko odesłania tych funkcji do przestrzeni nazw - nie ma potrzeby importowania klasy. –