2016-02-29 73 views
2

當我需要clojure腳本源文件中的名稱空間時,我可以在代碼中使用它。在repl中使用必需的名稱空間

E.g:

(ns my.core 
    (:require [mylib.core :as lib])) 

(lib/my-f) 

(def something 99) 

然而,當我嘗試調用(lib/my-f)的REPL裏面 - 通過(ns my.core)更改命名空間後 - 我不能訪問它。相反,ns內的所有其他定義都是可訪問的:如上面示例中的something

有沒有辦法訪問repl中的需求?或者我每次都必須在repl中手動要求它們?這當然是非常乏味的。

回答

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特殊切換到現有的命名空間,這將保留別名:

$ 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元位置: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特別切換到現有名稱空間。它也可以用來創建一個新的名字空間。

使用require將名稱空間加載到REPL中,然後使用in-ns切換到它們。

+0

感謝您的長時間答覆。 in-ns是我尋找的魔法。現在爲我節省了很多打字量.. –

1

只要你require切換到nsin-ns之前的命名空間,這一切都應該正常工作。令我費解的是something是可訪問的,意思是你的代碼被加載了:這應該意味着它的名字空間形式也被計算過了,因此你應該有它的別名。你確定你是從一個新的狀態做到這一點,並且沒有說獨立定義something?仔細檢查通過:

  1. 關閉REPL
  2. 開始新的REPL
  3. (require 'my.core)
  4. (in-ns 'my.core)
  5. 檢查你的問題的東西仍然是正確的。你仍然可以訪問something?你還可以不是訪問lib/my-f?我預測這兩件事情中的一件將會發生變化:您既不能訪問,也不能訪問兩者。
+0

再次檢查我的問題:我使用ns是in-ns - 這是我的錯誤。無論如何謝謝你!對我來說,現在看來,你的名單的第三點是沒有必要的。只是使用(in-ns'..)完成了所有的要求。 –

+0

@AntonHarald'in-ns'不加載代碼。它切換REPL的名稱空間(並根據需要創建它)。所以在你的情況下,'my.core'命名空間在你評估'(ns my.core)'之前已經被加載了。 –

相關問題