【问题标题】:Make clojure functions available in every namespace during development?在开发期间使每个命名空间中的 clojure 函数都可用?
【发布时间】:2017-04-04 01:14:01
【问题描述】:

在 Clojure 开发期间,我在 REPL 中使用了许多有用的辅助函数。这包括一些内置函数,如 docpprint,但也包括我自己的一些自定义函数,来自我的 user.clj。默认的 clojure 体验似乎是:

dev> (doc +)
;; works
dev> (in-ns 'project.core)
project.core> (doc +)
;; what is this "doc" thing you're talking about!?!?

这很烦人(我知道我可以在这里参考clojure.repl/doc)。有没有一种简单的方法可以确保在开发过程中某些东西可用,而不管我当前在哪个命名空间中操作?

【问题讨论】:

标签: clojure


【解决方案1】:

一种选择是将:repl-options 添加到project.clj 中的项目地图中:

(defproject myproj "1.0"
  :dependencies [[org.clojure/clojure "1.9.0-alpha15"]]
  :repl-options { :init-ns myproj.core
                  :init (require '[clojure.repl :refer :all]) })

...

$ lein repl
myproj.core=> (doc +)   ; works

【讨论】:

  • “init”代码似乎只在 REPL 启动时运行,因此如果您切换到另一个命名空间,则不会发生“require”调用。我想我需要一个在切换命名空间时运行的钩子。
【解决方案2】:

正如Alex Gherega 所提到的,自动和不加选择地将内容导入每个命名空间可能是个坏主意。但是,您可以创建一个宏(或者一个函数可能会起作用?)来帮助在需要时/如果需要导入与开发相关的命名空间。将其添加到您的user.clj。然后,如果您在另一个命名空间中工作并认为它有用,则可以运行 (user/import-useful-dev-stuff)(或任何您决定调用它的名称)。

对于它的价值,我几乎在 user 命名空间和 require 我需要的所有命名空间中进行所有 REPL 会话。我使用 Emacs,如果我需要更改另一个名称空间中的某些内容,我只需更改源代码,然后执行 C-c C-k(在启动苹果酒会话之后)以重新加载文件。如果您不使用 Emacs,只需使用 :reload 选项通过 require 从 REPL 重新加载即可。

【讨论】:

    【解决方案3】:

    除非您使用 boot 或 lein 或其他可以“神奇地”将此命名空间添加到您的 REPL 开发会话的形式,否则恐怕您每次都必须手动要求它。

    问题是命名空间具有避免名称冲突的良好预期作用。如果您有另一种方法告诉当前命名空间使用/需要另一个命名空间而不这样做,那么您将遇到很多其他问题。

    如果你没有使用 lein/boot,你可以just do as Alex Miller responded。要从 clojure.repl 或其他一些 ns API 中获得更可控的方式,只需在您感兴趣的命名空间中使用 requireuse 声明,例如:

    (ns 'project.core
       (:require [clojure.repl :refer [doc]]))
    

    【讨论】:

      【解决方案4】:

      如果您遇到这种情况,请执行以下操作:

      (clojure.core/refer-clojure)
      

      要求并从 clojure.core 加载所有内容。


      或者,如果存在project.core,另一种方法是:

      (require 'project.core)
      (in-ns 'project.core)
      

      通过require 加载命名空间将引用clojure.core。


      或者如果project.core 不存在,请执行以下操作:

      (ns project.core)
      

      ns 宏将同时执行 refer-clojurein-ns

      【讨论】:

      • 抱歉,这似乎是一种从“clojure.core”命名空间中引入符号的方法。我正在寻找的是一种在 REPL 开发过程中自动使 非核心 命名空间(例如“doc”、“pprint”或我自己的自定义函数)中的内容始终存在的方法。
      • 哦,是的。我误解了。 Clojure 中没有任何东西提供此功能,但有些工具对它有特别的支持。
      猜你喜欢
      • 2015-05-25
      • 2013-03-12
      • 1970-01-01
      • 2023-03-05
      • 1970-01-01
      • 2011-03-25
      • 2011-08-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多