2010-09-11 7 views
12

Tôi có một dự án được thiết lập với leiningen được gọi là techne. Tôi tạo ra một mô-đun được gọi là chà với một loại trong nó được gọi là Scrub và một chức năng gọi là foo.Làm thế nào để bạn sử dụng một loại bên ngoài không gian tên riêng của nó trong 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)))) 

Khi tôi chạy thử nghiệm, tôi nhận được lỗi:

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) 

Nếu tôi loại bỏ kiểm tra chà tất cả mọi thứ hoạt động tốt. Tại sao: sử dụng techne.scrub 'nhập' các định nghĩa hàm nhưng không phải định nghĩa kiểu? Làm thế nào để tôi tham khảo các định nghĩa kiểu?

Trả lời

15

deftype tạo một lớp, có thể bạn sẽ cần phải nhập lớp Java đó trong kiểm tra techne.scrub bằng (: import [techne.scrub Scrub]) theo định nghĩa ns của bạn.

Tôi thực sự đã viết lên điều này tương tự liên quan đến defrecord đây:

Một điều bạn có thể làm sẽ định nghĩa một hàm constructor trong chà:

(defn new-scrub [state] 
    (Scrub. state)) 

và sau đó bạn sẽ không cần phải nhập Scrub trong thử nghiệm chà.

+1

Tôi luôn sử dụng hàm tạo hàm vì lý do này và để xác thực. –

+1

Đúng, chúng tôi thấy hữu ích khi mở rộng tính năng xác thực để tự động thêm chức năng của hàm tạo với xác thực trường, hỗ trợ pprint cho biểu mẫu có thể đánh giá, v.v. –

+4

Lưu ý rằng câu trả lời này được đặt trước Clojure 1.4. Từ 1.4, hàm tạo (-> Scrub) và map (map-> Scrub) được tạo tự động bởi defrecord. Đó là phương thức xây dựng ưa thích và chỉ yêu cầu bạn tham chiếu các hàm đó vào không gian tên của bạn - không cần phải nhập lớp. –

0

Tôi thêm lần nhập nhưng gặp vấn đề tương tự. Tôi đang thử nghiệm với gói Expectations 2.0.9, cố gắng nhập deftype Node và giao diện INode.

Trong core.clj:

(ns linked-list.core) 

(definterface INode 
    (getCar []) 
    (getCdr []) 
    (setCar [x]) 
    (setCdr [x])) 

(deftype Node [^:volatile-mutable car ^:volatile-mutable cdr] 
    INode 
    (getCar[_] car) 
    (getCdr[_] cdr) 
    (setCar[_ x] (set! car x) _) 
    (setCdr[_ x] (set! cdr x) _)) 

Trong core_test.clj:

(ns linked-list.core-test 
    (:require [expectations :refer :all] 
      [linked-list.core :refer :all]) 
    (:import [linked-list.core INode] 
      [linked-list.core Node])) 

và đầu ra từ Lein autoexpect:

*************** Running tests *************** 
Error refreshing environment: java.lang.ClassNotFoundException: linked-list.core.INode, compiling:(linked_list/core_test.clj:1:1) 
Tests completed at 07:29:36.252 

Các gợi ý để sử dụng một phương pháp nhà máy, tuy nhiên, là một công việc khả thi.