Clojureの独自の名前空間の外側のタイプをどのように使用しますか?
質問
Techneと呼ばれるLeiningenと一緒にプロジェクトをセットアップしました。スクラブと呼ばれるタイプのスクラブとFOOと呼ばれる関数を含むスクラブというモジュールを作成しました。
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))))
テストを実行すると、エラーが表示されます。
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)
テストスクラブを削除すると、すべてが正常に機能します。なぜ:techne.scrubを使用して、型定義ではなく関数定義を「インポート」しますか?タイプ定義を参照するにはどうすればよいですか?
解決
なぜなら deftype クラスを生成すると、NS定義で(:[techne.scrub scrub])を使用してtechne.scrub-testでそのJavaクラスをインポートする必要があります。
私は実際にこの同じことをここでdefrecordに関して書きました:
あなたができるもう1つのことは、スクラブでコンストラクター関数を定義することです。
(defn new-scrub [state]
(Scrub. state))
そして、テストスクラブにスクラブをインポートする必要はありません。
他のヒント
インポートを追加しますが、同じ問題が発生します。 DeftypeノードとインターフェイスInodeをインポートしようとしているPhosdationsパッケージ2.0.9でテストしています。
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) _))
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]))
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
ただし、工場の方法を使用するという提案は、実行可能な回避策です。
所属していません StackOverflow