2012-04-04 13 views
5

due fileConfuso sulla risoluzione del nome di classe

types.clj:

(ns test.types) 

(defrecord Price [date price]) 
(defrecord ProductPrice [name prices]) 

core.clj (è tutto OK)

(ns test.core 
    (:use [test.types]) 
    (:use [clojure.string :only (split)])) 


(defn read-data [file] 
    (let [name (subs (.getName file) 0 4)] 
    (with-open [rdr (clojure.java.io/reader file)] 
     (doall (map #(apply ->Price (split % #"\t")) (drop 2 (line-seq rdr))))))) 

core.clj (java.lang.IllegalArgumentException: Impossibile per risolvere classname: ProductPrice)

(ns test.core 
    (:use [test.types]) 
    (:use [clojure.string :only (split)])) 


(defn read-data [file] 
    (let [name (subs (.getName file) 0 4)] 
    (with-open [rdr (clojure.java.io/reader file)] 
     (ProductPrice. name (doall (map #(apply ->Price (split % #"\t")) (drop 2 (line-seq rdr)))))))) 

core.clj (è tutto OK)

(ns test.core 
    (:use [test.types]) 
    (:use [clojure.string :only (split)])) 

(defrecord tProductPrice [name prices]) 
(defn read-data [file] 
    (let [name (subs (.getName file) 0 4)] 
    (with-open [rdr (clojure.java.io/reader file)] 
     (tProductPrice. name (doall (map #(apply ->Price (split % #"\t")) (drop 2 (line-seq rdr))))))) 

core.clj (java.lang.IllegalStateException: -> ProductPrice fa già riferimento: # 'test.types/-> ProductPrice in namespace: test.core)

(ns test.core 
    (:use [test.types]) 
    (:use [clojure.string :only (split)])) 

(defrecord ProductPrice [name prices]) 
(defn read-data [file] 
    (let [name (subs (.getName file) 0 4)] 
    (with-open [rdr (clojure.java.io/reader file)] 
     (ProductPrice. name (doall (map #(apply ->Price (split % #"\t")) (drop 2 (line-seq rdr))))))) 

Sono totalmente confuso su queste eccezioni. E non riesco a trovare altri usi su "record" tranne alcuni esempi più semplici di clojure.org e libri.

Qualsiasi aiuto, grazie mille!

risposta

9

defrecord crea una classe java nel pacchetto chiamato dopo lo spazio dei nomi corrente. (ProductPrice. ...) è una chiamata al costruttore di quel tipo; questo è java interop, non una semplice chiamata di funzione.

Non è possibile fare riferimento a una classe definita al di fuori di java.lang o allo spazio dei nomi corrente a meno che non si specifichi esplicitamente l'importazione o si specifichi il nome completo del pacchetto. Ciò include chiamare il suo costruttore.

Quindi, per risolvere il problema è necessario importare prezzo e prezzo del prodotto.

(ns test.core (:import [test.types Price])) 
(Price. ...) 

o chiamare la classe + pacchetto completo Nome:

(test.types.Price. ...) 
+2

noti che trattino/sottolineatura pressare nei nomi dello spazio dei nomi provoca confusione qui. Se "' defrecord'' qualcosa nel namespace '' clj-test'' creerà una classe nel pacchetto '' clj_test'' e il tuo '': import'' dovrà riflettere questo – sw1nn

+0

@Joost Diepenmaat Grazie! Perché '-> Price' può essere utilizzato senza importazione? E 'importare' sembra non funzionare per me, ancora "java.lang.RuntimeException: java.lang.ClassNotFoundException: test.types.ProductPrice" – Kane

+0

-> Il prezzo è una funzione di aiuto generata addizionalmente che è una funzione reale del clojure, e quindi esportata quando usi il pacchetto. Inoltre, è necessario assicurarsi che i tipi di record siano compilati ('use' o' require' lo spazio dei nomi in cui sono definiti) prima di poterli importare. Se non riesci a farlo funzionare, ti preghiamo di creare una nuova domanda con un codice di esempio. –

Problemi correlati