【问题标题】:Calling Clojure Functions Loaded from File调用从文件加载的 Clojure 函数
【发布时间】:2016-07-03 15:41:17
【问题描述】:

我正在为吉他指法谱开发 clojure DSL,我希望通过在已知文件位置(例如 plugins.clj)中定义一个名为 apply-clojure-plugin 的函数来允许用户编写插件。

我试过了:

  • load 文件并调用函数(导致“无法找到符号:apply-clojure-function”。
  • 添加declare 以避免上述问题(导致“尝试调用未绑定的 fn”)

我猜这是某种命名空间问题,但我不知道如何在这里使用ns-resolve(如果有必要的话)。

编辑:我最终用resolve 解决了这个问题。问题是apply-clojure-plugin 没有在编译时定义(因为它是在文件中定义的),所以在编译过程中会抛出错误。调用(resolve 'apply-clojure-plugin) 工作正常。

【问题讨论】:

  • 你不需要ns-resolvens-resolve 用于根据另一个 ns 的映射查找符号,为了您的目的,您所需要的只是映射到另一个 ns - 您不需要其他 ns 看到的东西,只需要它的东西定义。

标签: clojure


【解决方案1】:

您要么希望(load "plugins")(如果包含该文件的目录位于类路径上),要么希望(load-file "path/to/plugins.clj")从相对于执行的已知文件路径(或绝对路径)加载。

如果文件不包含ns 表单,您将能够直接访问其定义。否则,您将需要知道文件定义了哪个 ns,并且可以使用 alias 将该命名空间映射到您自己的命名空间:

;; make a new namespace for demonstration purposes
:user=> (ns foo)
nil
;; a definition in the other namespace
:foo=> (def bar "hello")
#'foo/bar
;; switch back to the original namespace
:foo=> (in-ns 'user)
#object[clojure.lang.Namespace 0x14a50707 "user"]
;; our definition is not visible
:user=> (resolve 'bar)
nil
;; but it is visible based on the fully qualified namespace
+user=> (resolve 'foo/bar)
#'foo/bar
;; using alias, we can make a convenient shorthand
+user=> (alias 'f 'foo)
nil
+user=> f/bar
"hello"

【讨论】:

  • 这似乎对我不起作用。在文件中使用(ns plugins) 声明,如果我调用load-file,然后我得到完全限定的函数:No such namespace: plugins。没有ns 我得到Unable to resolve symbol: apply-clojure-plugin in this context
  • (apropos "plugin") 返回什么?
  • (apropos "plugin") 返回(plugins/apply-clojure-plugin),但是当我添加对plugins/apply-clojure-plugin 的调用时,我仍然得到No such namespace: plugins。看来错误是在编译时发生的,这是有道理的,因为在文件运行之前不会创建 plugins 命名空间。
  • 对,这就是你使用resolve的原因,就像我的例子中一样
猜你喜欢
  • 1970-01-01
  • 2011-02-24
  • 2017-03-12
  • 1970-01-01
  • 2020-11-25
  • 1970-01-01
  • 2016-10-21
  • 1970-01-01
相关资源
最近更新 更多