lein repl (-main "something")和lein run "something"之间的区别

4

新手Clojure和leiningen问题:

给定以下代码片段,这可以从lein repl中工作:

==> (-main "something")

生成预期的“命令:something ……运行……完成”,但无法从命令行中使用:

me pallet1]lein run "something"

会产生"Command: something ... error: not resolved as a command"的错误。

为什么?/ 我该如何解决?

复现步骤:

lein new eg

接下来编辑生成的项目文件,添加:main eg.core来定义主函数,并编辑生成的src/eg/core.clj文件,将以下内容粘贴到其中:

core.clj

(ns eg.core)
(defn something [] (println "Something!"))

(defn run-command-if-any [^String commandname]
    (printf "Command: %s ..." commandname)
    (if-let [cmd (ns-resolve *ns* (symbol commandname))] 
      (
        (println "running ...") (cmd) (println "done.")
      )
      (println "error: not resolved as a command.")
    ))
(defn -main [ commandname ] (run-command-if-any commandname))

那么

lein repl
eg.core=> (-main "something")

运行works(即打印“Something!”),但是运行lein run something不起作用(即打印“错误:未解析”消息)


什么是 something?你在哪里定义它?如果它不在你的 clj 文件中,并且你在 repl 中定义了它,那么运行 lein run 的时候它是不知道它的存在的,因为它只会读取你的 clj 文件。 - Mikita Belahlazau
如果在REPL中运行这两个代码,会出现“未解析”的错误。 - Mikita Belahlazau
1
正如Nikita所说,你的示例代码中没有定义repl/something。即使你定义了它,也会出现NullPointerException,因为你试图调用(println "running")的结果。 - Joost Diepenmaat
好的,我已经将“something”的定义添加到代码引用中。实际代码有几个函数(与palletOps相关),我的目标是从命令行运行其中一个函数。 - Chris F Carroll
我猜我本可以问一个替代性问题:“如何将Clojure函数的名称作为命令行参数传递并运行?”run-command-if-any应该可以做到这一点,但目前只能在repl中使用,而不能从命令行中使用。 - Chris F Carroll
感谢您指出空指针异常的来源 - Chris F Carroll
2个回答

6

问题在于,当您从lein运行它时,您的默认命名空间是"user"命名空间:

(defn -main [ commandname ] (println *ns*))

打印出#<Namespace user>。因为它来自另一个命名空间,所以不包含something函数。你有几个选择:

  1. 传递完全限定的函数名称:your-namespace/something而不是something
  2. 使用your-namespace代替*ns*(ns-resolve 'your-namespace (symbol commandname))
  3. -main中更改命名空间为your-namespace

方法3的示例:

(defn -main [ commandname ] 
   (in-ns 'your-namespace)
   (run-command-if-any commandname))

如果您想依次调用多个函数,应使用do:

(do (println "Hello")
    (println "World"))

不仅仅是像 ( (println "hello") (println "World")) 这样的括号。

2

Lein Exec插件在项目上下文中编写脚本非常有用。我已广泛使用它来编写Clojure的Jenkins作业和其他脚本情况。

lein exec -pe '(something ...) (something-else) (save-results)'

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接