2010-06-27 18 views
4

我試圖嵌入一個swank clojure repl到我的應用程序中,以便在應用程序正在運行時與連接的東西進行連接。但是,在開始repl之後,我無法弄清楚如何訪問封閉環境。嵌入式swank-clojure repl可以訪問它嵌入的程序嗎?

嵌入的自吹,Clojure的REPL是很容易的:

(ns mytest 
    (:use [swank.swank :exclude [-main]]) 
    (:gen-class)) 

(defn -main [& args] 
    (let [x 123] 
    (swank.swank/start-repl))) 

運行程序..然後通過在Emacs:

M-x slime-connect 

這工作正常,我連接。現在,我希望,這將工作:

(println x) 
;; 123 (what I was hoping for) 
;; Unable to resolve symbol: x in this context (cruel reality) 

所以不作爲的方式工作,以當前的環境傳遞到嵌入式REPL。

有沒有什麼方法讓嵌入式REPL與我的正在運行的程序進行交互?

如果不是,那麼嵌入REPL的原因是什麼?

如果它有什麼區別,我試圖運行它作爲JAR。

此線程似乎有關,但我無法從任何地方獲得:

Embedding swank-clojure in java program

回答

5

let結合的當地人詞法範圍,從而swank.swank/start-repl不會被一個let形式包裝的影響圍繞着它的呼籲。然而,運行REPL就能require/use您的應用程序的類路徑中的任何Clojure的命名空間(或使用in-ns到REPL的命名空間切換到其中的一個),並import任何Java類的類路徑,讓你做一些非常有用的東西,比如函數被重新定義,審查和改變任何參考文獻的內容/原子的瓦爾持有的權益/其他的東西,調用函數/ Java方法等

請注意,你可能不應該(:use swank.swank)ns形成;改爲(:require swank.swank)。不同之處在於前者將所有swank.swank的公共變量引入到您的名稱空間中,而後者不包含(use = require + refer,詳見(doc use)等)。您似乎使用命名空間限定的符號來訪問Swank的Vars,因此您甚至可能不需要更改其餘的代碼,並且避免了混淆名稱空間。或者,(:use [swank.swank :only [start-repl]]);這隻會引入start-repl Var,您可以直接使用它,而不需要swank.swank/位。

+1

感謝您的答案米哈爾和指出我的問題:使用/:要求的用法。關鍵是您對命名空間的評論。我以前試過(def x),它看起來不工作,因爲我的REPL位於錯誤的命名空間中。對於其他感興趣的人,似乎這樣的東西似乎工作.. (def x(atom nil)) (defn -main [&args] (do(reset!x「123」)(start-swank) )) 然後運行,連接粘液,並在REPL中,確保切換到正確的命名空間: (ns「whatever」) – allclaws 2010-06-27 17:20:02

相關問題