2010-09-11 16 views
12

Techne adlı leiningen ile kurulmuş bir projem var. Scrub olarak adlandırılan bir tiple bodur ve foo adında bir işlev oluşturdum.Clojure'da kendi ad alanının dışında bir türü nasıl kullanıyorsunuz?

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:

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) 

Ben ise: Testi çalıştırdığınızda

(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)))) 

, hatası alıyorum test ovma çıkarın her şey iyi çalışıyor. Neden: techne.scrub 'import' işlev tanımlarını kullanın ama tip tanımlarını değil? Tür tanımlarına nasıl başvururum?

cevap

15

deftype bir sınıf ürettiğinden, ns tanımınızda (: import [techne.scrub Scrub]) ile şu Java sınıfını techne.scrub-testinde içe aktarmanız gerekecektir.

Eğer keselenmenin yapıcı işlevini tanımlamak olacaktır yapabileceği başka bir şey:

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

Aslında burada defrecord göre bu aynı şey yukarı yazdım

ve daha sonra, Scrub'ı test-fırçalamada içe aktarmanız gerekmeyecektir.

+1

Bu nedenle her zaman yapıcı işlevlerini ve doğrulama için kullanırım. –

+1

Yep, alan onaylama, pprint desteği ile değerlendirilebilen bir forma vb. Gibi kurucu işlevlerini otomatik olarak eklemek için defrecord'ı genişletmenin faydalı olduğunu bulduk. –

+4

Bu yanıtın Clojure 1.4 öncesi olduğunu unutmayın. 1.4'den beri, konumsal (-> Fırçalama) ve harita (map-> Scrub) kurucusu otomatik olarak defrecord ile oluşturulacaktır. Bu tercih edilen yapım yöntemidir ve sadece bu işlevleri ad alanınıza yönlendirmeniz gerekir - sınıfı içe aktarmaya gerek yoktur. –

0

İçe aktarmayı ekliyorum, ancak aynı sorunu yaşıyorum. Ben deftype Düğümü ve arabirim INode ithal etmeye çalışırken Expectations paketi 2.0.9 ile test ediyorum. core.clj olarak

: core_test.clj olarak

(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) _)) 

:

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

ve Lein autoexpect çıktı:

*************** 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 

fabrika yöntemi kullanmak için öneri Ancak, uygulanabilir bir çalışmadır.

İlgili konular