Ho un progetto con leiningen chiamato techne. Ho creato un modulo chiamato scrub con un tipo chiamato Scrub e una funzione chiamata foo.Come si usa un tipo al di fuori del proprio spazio dei nomi 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))))
Quando eseguo il test, ottengo l'errore:
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)
Se io rimuovere test-scrub tutto funziona bene. Perché: usare techne.scrub 'importa' le definizioni di funzione ma non le definizioni di tipo? Come faccio a fare riferimento alle definizioni del tipo?
Uso sempre le funzioni di costruzione per questo motivo e per la convalida. –
Sì, abbiamo trovato utile estendere defrecord per aggiungere automaticamente funzioni di costruzione con convalida dei campi, supporto pprint a un form evalable, ecc. –
Si noti che questa risposta è precedente a Clojure 1.4. Dalla versione 1.4, un costruttore posizionale (-> Scrub) e mappa (map-> Scrub) verrà automaticamente creato da defrecord. Questo è il metodo di costruzione preferito e richiede solo che tu faccia riferimento a tali funzioni nel tuo spazio dei nomi - non è necessario importare la classe. –