Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Confused about resolving of classname

Tags:

clojure

two files

types.clj:

(ns test.types)

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

core.clj (It's 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: Unable to resolve 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 (It's 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 already refers to: #'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)))))))

I totally confused about these exceptions. And I can't find any more usage about 'record' except some simplest examples from clojure.org and books.

Any help, Thank you very much!

like image 913
Kane Avatar asked Apr 04 '12 05:04

Kane


1 Answers

defrecord creates a java class in the package named after the current namespace. (ProductPrice. ...) is a call to the constructor of that type; this is java interop - not a plain function call.

You cannot refer to a class defined outside of java.lang or the current namespace unless you explicitly import it or specify the full package name. This includes calling its constructor.

So, to fix the problem you need to import Price and ProductPrice.

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

or call the full class+package name:

 (test.types.Price. ...)
like image 164
Joost Diepenmaat Avatar answered Nov 05 '22 01:11

Joost Diepenmaat