2016-09-30 4 views
0

私はこのマルチ関数をclojureで書いています。defmultiディスパッチ関数の使用に問題がある

(defmulti printlmt (fn [s] (> (count s) 10))) 
(defmethod printlmt true [s] (println s)) 
(defmethod printlmt false [s] (println (take 10 s))) 

私はその後

(printlmt "test") 

...以下のようにそれを実行しようとする。しかし、私は次のエラーを取得しておきます。

IllegalArgumentException No method in multimethod 'printlmt' for dispatch value: 4 clojure.lang.MultiFn.getFn (MultiFn.java:156) 

私の理解では、匿名関数はtrueの値を返すべきです。無名関数が4を返すのはなぜですか?

私は別にディスパッチ関数を呼び出した場合、この場合、この

((fn [s] (> (count s) 0)) "test") 

のように、それはtrueを返します!

編集:私は私が持っている端末のテキストを追加している :あなたがメソッドを再定義するために、あなたのREPLを再起動したくない場合は

startingclojure.core=> (defmulti printlmt (fn [s] (> (count s) 10))) 
nil 
startingclojure.core=> (defmethod printlmt true [s] (println s)) 
#object[clojure.lang.MultiFn 0x3315fe88 "[email protected]"] 
startingclojure.core=> (defmethod printlmt false [s] (println (take 10 s))) 
#object[clojure.lang.MultiFn 0x3315fe88 "[email protected]"] 
startingclojure.core=> 

startingclojure.core=> (printlmt "test") 

IllegalArgumentException No method in multimethod 'printlmt' for dispatch value: 4 clojure.lang.MultiFn.getFn (MultiFn.java:156) 
startingclojure.core=> 
+0

あなたのコードは私のために動作します – Lee

+0

@Lee実際のコンソールテキストを追加しました。何か間違っているかどうか分かりますか? – Teddy

+2

両方のコードで問題はありません。あなたは退会してからreplを再起動しようとしましたか?ばかげた質問ですが、おそらくprintlmtの古い誤った定義はまだここにあります –

答えて

2

は、使用remove-method

https://clojuredocs.org/clojure.core/remove-method

(remove-method printlmt true) 

次に再定義します。ns-unmapだけでなく、すべてのメソッドを再定義する必要があります:あなたはノート

(ns-unmap *ns* 'printlmt) 

を使用することができます

EDIT

+0

ありがとう!これは動作し、また(remove-all-methods multifn)も動作します。これはdefmultiディスパッチ関数を再定義するのに役立ちません。私は別の機能でdefmultiをやり直すが、それでもやはり古い方法で動作する。たとえば、私の場合、私はスイッチの長さを10から5に変更しました。それでも "真の"方法は長さ10まで呼び出されます。 – Teddy

+0

@Teddyは私の編集を参照してください。 –

+0

ありがとう! ns-unmapが機能しました!しかし、おそらくこれは別の質問ですが、defmulti内のすべてのdefメソッドをリストする方法を見つけることができませんでした。このメソッドは、名前空間上でdirを呼び出す際には表示されません。また、マルチメソッド名でsourceを呼び出すことは役に立ちません。 – Teddy

関連する問題