【问题标题】:access library functions in leiningen REPL访问 leiningen REPL 中的库函数
【发布时间】:2016-02-14 00:10:52
【问题描述】:

为了开发一个库,我从一个 lein 项目开始,像这样调用:

lein new mylib

如果我现在打电话给lein install,我可以在其他项目中访问我的库。但是尝试立即测试我编写的函数失败了:

lein repl
...
(dir mylib.core)
Exception No namespace: mylib.core found  clojure.core/the-ns (core.clj:4008)

我是否必须在 project.clj 文件中添加一些内容?

【问题讨论】:

  • REPL 从哪个命名空间开始?我通常通过(in-ns NAME)切换。
  • dir 也应该适用于其他命名空间。但是,尝试 (in-ns ..) 会引发上述相同的错误...
  • in-ns 如果在加载该命名空间的代码之前运行,会给你一个看似无法使用的 repl。 (clojure.core/refer-clojure) 将把 repl 从那个状态中解救出来。
  • 只是为了确定:您的文件中有相应的(ns BLAH BLAH)?没有错字吗?

标签: clojure clojurescript leiningen


【解决方案1】:

为了使用库,您必须加载代码 - 仅在类路径中是不够的。

当然,您可以在文件中的 ns 声明中轻松做到这一点,但在 repl 中使用 (require '[my-lib.whatever :as w]) 会更容易,之后可以按预期调用 (w/foo) (w/bar) 等。您也可以使用(in-ns 'my-lib.whatever) 来切换到命名空间,但这不会给您带来好的结果,除非您之前使用过requireuseload-file 等先获取定义。

【讨论】:

  • 有趣的是,您只需使用 Figwheel (in-ns 'my-lib.whatever)。见here
  • 这是因为 figwheel 正在为您预加载 ns。您不能保证每个配置都这样做(即使您的配置正确,ns 表单中的拼写错误也会破坏这一点)。
【解决方案2】:

假设您创建了一个名为 clj-foo 的新库。

% lein new clj-foo

开始你的repl。

% cd clj-foo
% lein repl

在 repl 中,将主入口点加载到您的库并切换到其命名空间。

(load-file "src/clj_foo/core.clj")
(ns clj-foo.core)

现在您位于 clj-foo.core 命名空间中,请确保在 repl ns 中重新添加以使 doc 等内容可用。

(use 'clojure.repl)

就是这样。您已经准备好开始调用库中的函数了。请注意,如果其他库文件是由 clj_foo/core.clj 顶部的命名空间声明加载的,则它们将在 clj-foo.core 命名空间中可用。如果没有,那么您还需要使用它们的路径调用 load-file

如果您在core.clj 中进行更改。您可以再次调用load-file 来获取新代码。随着您的进步,您可以使用 cider 来促进加载各个函数和文件。但这是另一个问题。 :)

【讨论】:

    【解决方案3】:

    您需要添加一个依赖项才能使用来自另一个项目的库。为此,将向量(元组 2)添加到作为 project.clj 文件中 :dependencies 键的值的向量。这是一个例子:

    :dependencies [[org.clojure/clojure "1.7.0"]
                   [org.clojure/clojurescript "1.7.170"]
                   [org.clojure/core.async "0.2.371"]
                   [default-db-format "0.1.0-SNAPSHOT"]
                   [com.andrewmcveigh/cljs-time "0.3.14"]]
    

    我自己的本地图书馆称为default-db-format。与为com.andrewmcveigh/cljs-time 添加依赖关系确实没有什么不同。

    正如您所说,您已经可以做到这一点,但是在获得与库本身项目的 REPL 连接时遇到了麻烦。当你去(in-ns 'some-path)时,你需要some-path前面的单引号。请注意,some-path 与您的库名称不同。

    您可以使用 figwheel repl 而不是使用 lein repl - 如果您的项目是使用 figwheel 设置的。我的图书馆只有一个入口点,那就是lein figwheel devcards。之后,我可以毫无问题地进入命名空间并尝试一个函数:

    cljs.user=> (in-ns 'default-db-format.core)
    nil
    default-db-format.core=> (check 1 2)
    

    正如 noisesmith 所说,在您的 IDE 中使用 REPL 是最好的设置。无需繁琐的输入,只需单击按钮(或击键)即可调出预配置的 REPL(每个命名空间)。 Figwheel/Cursive 设置说明here.

    【讨论】:

    • 不幸的是,在将我自己的库添加到您的示例中描述的依赖项后,我一直收到相同的错误。
    • 是的 - 我不太喜欢/使用lein repl。像往常一样在测试之前回答这个问题!我正在研究用 figwheel 来做这件事,它也给你一个repl
    • lein install 有效/没有给我错误。如果依赖项有问题,它会这样做。 Figwheel 是一个很酷的东西,但更适合 Web 开发/或 nodejs 应用程序 - 至少我是这么认为的。
    • 我的小库最初是一个没有 UI 的真正库。但是,在使用 boot 和 cljs.test 等“巡视”时,我想为什么不回到我所知道的工作。即使您的库没有 UI,您的测试也可以(开发卡而不是测试!)。
    • 是的,但这当然是最好的:有一个 repl 可以在任何时候热重新加载库代码。变化。
    【解决方案4】:

    以下配置我也遇到了同样的问题:

    Leiningen 2.9.0 on Java 1.8.0_201 Java HotSpot(TM) 64-Bit Server VM
    

    我的文件看起来像这样,从 repl 中我想调用 foo 函数

     (ns cljtest.test
      (:gen-class))
    
    (defn foo [input]
      (assoc {} "a" 123)) 
    

    这两种方法对我来说都很好。

    1)切换到合适的命名空间:

    cljtest.core=> (in-ns 'cljtest.test)
    #object[clojure.lang.Namespace 0x90175dd "cljtest.test"]
    cljtest.test=> (foo nil)
    {"a" 123}
    cljtest.test=>
    

    2)需要适当的命名空间:

    cljtest.core=> (require '[cljtest.test :as test])
    nil
    cljtest.core=> (test/foo nil)
    {"a" 123}
    cljtest.core=>
    

    【讨论】:

      猜你喜欢
      • 2013-04-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-01
      • 1970-01-01
      • 2014-02-13
      • 2020-03-26
      • 1970-01-01
      • 2015-09-21
      相关资源
      最近更新 更多