【问题标题】:java.lang.IllegalArgumentException error depending on symbol names used - Clojurejava.lang.IllegalArgumentException 错误取决于使用的符号名称 - Clojure
【发布时间】:2019-01-27 13:55:39
【问题描述】:

我是 Clojure 的初学者。我正在执行一项操作两次,但更改了符号 langlanguage

一种情况运行良好,另一种情况抛出错误: java.lang.IllegalArgumentException: No method in multimethod 'my-method' for dispatch value: null

我不确定这是由 Clojure 语法引起的,还是我的 linux 配置有问题。我有 Debian Stretch 和 boot.clj。

错误发生在终端中。这是代码和错误的两个方面:

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

我必须在它与language 一起使用之前添加它,但不适用于lang。当我用mymetho-dgreeting 更改my-method 符号名称时,它也可以正常工作。

【问题讨论】:

    标签: linux terminal clojure boot-clj


    【解决方案1】:

    defmulti 定义了一个 var,随后对 defmulti 的同名调用什么也不做,所以你的第二个 defmulti 调用无效,原来的调度函数仍然存在。 remove-methodremove-all-methods 用于删除 defmethod 定义,但要删除 defmulti 定义(无需重新启动 REPL),您可以使用 alter-var-root 将 var 设置为 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!"
    

    你可以使用ns-unmap来达到类似的效果:

    (ns-unmap *ns* 'my-method)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-14
      • 1970-01-01
      相关资源
      最近更新 更多