当我在clojure-script源文件中需要一个命名空间时,我可以在代码中使用它。
E.g:
(ns my.core
(:require [mylib.core :as lib]))
(lib/my-f)
(def something 99)
但是,当我尝试在repl中调用(lib/my-f)
时 - 通过(ns my.core)
更改命名空间后 - 我无法访问它。相比之下,ns中的所有其他定义都是可访问的:例如上面示例中的something
。
有没有办法访问repl中的要求?或者我每次都必须在repl中手动要求它们?当然,这将非常繁琐。
答案 0 :(得分:6)
如果使用ns
更改ClojureScript REPL中的命名空间,则会将命名空间别名设置为与ns
形式中使用的别名相匹配。
这是一个说明这个概念的例子:
$ java -jar cljs.jar -m cljs.repl.nashorn
To quit, type: :cljs/quit
cljs.user=> (ns foo.core (:require [clojure.string :as string]))
foo.core=> (string/starts-with? "abc" "a")
true
foo.core=> (ns bar.core)
bar.core=> (ns foo.core)
foo.core=> (string/starts-with? "abc" "a")
WARNING: No such namespace: string, could not locate string.cljs, string.cljc, or Closure namespace "" at line 1 <cljs repl>
WARNING: Use of undeclared Var string/starts-with? at line 1 <cljs repl>
ReferenceError: "string" is not defined
如果您使用in-ns
REPL special更改为现有命名空间,则会保留别名:
$ java -jar cljs.jar -m cljs.repl.nashorn
To quit, type: :cljs/quit
cljs.user=> (ns foo.core (:require [clojure.string :as string]))
foo.core=> (string/starts-with? "abc" "a")
true
foo.core=> (ns bar.core)
bar.core=> (in-ns 'foo.core)
nil
foo.core=> (string/starts-with? "abc" "a")
true
一个有趣的相关方面:如果您使用require
REPL特殊内容,它将在引擎盖下使用ns
形式,并在保留现有别名的表单中加入特殊元素:
$ java -jar cljs.jar -m cljs.repl.nashorn
To quit, type: :cljs/quit
cljs.user=> (require '[clojure.string :as string])
nil
cljs.user=> (require '[clojure.string :as str])
nil
cljs.user=> (string/starts-with? "abc" "a")
true
cljs.user=> (str/starts-with? "abc" "a")
true
如果您感到好奇,这是:merge true
meta:https://github.com/clojure/clojurescript/blob/r1.7.228/src/main/clojure/cljs/repl.cljc#L679
分析师很尊重它:https://github.com/clojure/clojurescript/blob/r1.7.228/src/main/clojure/cljs/analyzer.cljc#L1953
通过了解其工作原理,它应该提供一些深入了解为什么在REPL中直接评估ns
形式(没有merge
元)会导致别名被清除的原因。
简而言之,请避免直接使用ns
special来更改REPL中的命名空间。而是使用它在REPL中创建新的命名空间,同时指定任何必需的命名空间。
使用in-ns
REPL special切换到现有命名空间。它还可以用于创建新的命名空间。
使用require
将命名空间加载到REPL中,然后使用in-ns
切换到它们。
答案 1 :(得分:1)
只要您在使用require
或ns
切换到命名空间之前in-ns
命名空间,这一切都可以正常工作。对我来说令人费解的是something
是可访问的,这意味着您的代码已被加载:这应该意味着它的名称空间形式也被评估,因此您应该可以使用其别名。你确定你是从一个新鲜的状态做到这一点,并且没有,比如说,独立定义something
吗?仔细检查:
(require 'my.core)
(in-ns 'my.core)
something?
你还能不访问lib/my-f
吗?我预测这两件事中的一件会改变:你应该既不能访问,也不能两者都访问。