0

I am a beginner at Clojure. I am performing one operation twice, but with changed symbols lang against language

One case it is working well, another is throwing an error: java.lang.IllegalArgumentException: No method in multimethod 'my-method' for dispatch value: null

I am not sure if it is caused by an Clojure syntax or there is something wrong in my linux configuration. I have Debian Stretch and boot.clj.

The error happens in the terminal. Here you are the both peaces of code an the error:

s@lokal:~$ boot repl
nREPL server started on port 36091 on host 127.0.0.1 - nrepl://127.0.0.1:36091
java.lang.Exception: No namespace: reply.eval-modes.nrepl found
REPL-y 0.4.1, nREPL 0.4.4
Clojure 1.8.0
OpenJDK 64-Bit Server VM 1.8.0_181-8u181-b13-2~deb9u1-b13
        Exit: Control+D or (exit) or (quit)
    Commands: (user/help)
        Docs: (doc function-name-here)
              (find-doc "part-of-name-here")
Find by Name: (find-name "part-of-name-here")
      Source: (source function-name-here)
     Javadoc: (javadoc java-object-or-class-here)
    Examples from clojuredocs.org: [clojuredocs or cdoc]
              (user/clojuredocs name-here)
              (user/clojuredocs "ns-here" "name-here")
boot.user=> (do
       #_=> (defmulti my-method (fn[x] (x "lang")))
       #_=> (defmethod my-method "English" [params] "Hello!")
       #_=> (def english-map {"id" "1", "lang" "English"})
       #_=>     (my-method english-map)
       #_=> )
"Hello!"
boot.user=> 

boot.user=> (do
       #_=> (defmulti my-method (fn[x] (x "language")))
       #_=> (defmethod my-method "English" [params] "Hello!")
       #_=> (def english-map {"id" "1", "language" "English"})
       #_=>     (my-method english-map)
       #_=> )

java.lang.IllegalArgumentException: No method in multimethod 'my-method' for dispatch value: null
boot.user=>

I must add that before it worked with language but not with lang. It also turned to work or did not when I was changing a my-method symbol name with mymetho-d or greeting.

1 Answer 1

3

defmulti defines a var, and subsequent calls to defmulti with the same name do nothing, so your second defmulti call is ineffective and the original dispatch function remains. There's remove-method and remove-all-methods for removing defmethod definitions, but to remove a defmulti definition (without restarting REPL) you can use alter-var-root to set the var to nil:

(defmulti my-method (fn [x] (x "lang")))
(defmethod my-method "English" [params] "Hello!")
(def english-map {"id" "1", "lang" "English"})
(my-method english-map)
=> "Hello!"

(alter-var-root #'my-method (constantly nil)) ;; set my-method var to nil

(def english-map {"id" "1", "language" "English"})
(defmulti my-method (fn [x] (x "language")))
(defmethod my-method "English" [params] "Hello!")
(my-method english-map)
=> "Hello!"

You can use ns-unmap to similar effect:

(ns-unmap *ns* 'my-method)
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.