在以前的文章《生活在REPL中:工具與程序一體》中,我描繪了把Clojure REPL
當作SHELL
來使用的場景,在REPL
中作諸如訪問數據庫、加解密等平常開發工做。java
但使用REPL
中最鬱悶的就是依賴的類庫沒法動態加載。例如代碼運行到一半,突然發現須要解析JSON
字符串,不得不退出REPL
,在project.clj
中添加依賴的JSON
解析包,而後從新進入REPL並敲一堆代碼恢復到以前退出的場景。這一方面Clojure
或者說Java
沒法作到像SHELL
那樣簡便地修改PATH
環境變量同樣修改CLASSPATH
,以實現動態加載類庫的目的。shell
今天終於下決心解決這個問題,而且我相信確定已經有解決方案了!網絡上搜索了半天,終於在一篇StackOverflow
的帖子中看到了相關的解答:使用alembic
,可實現動態加載類庫的功能。具體方法以下:數據庫
project.clj
中引入[alembic "0.3.2"]
或更高版本lein repl
(require 'alembic.still)
(alembic.still/distill '[org.clojure/data.codec "0.1.0" :exclusions [org.clojure/clojure]])
其中alembic.still/distill
可用兼容project.clj
的語法來動態加載依賴的類庫,而後就能夠在後續的REPL中使用動態加載的類了。網絡
找了方法後,爲了方便後續的使用,我想修改$HOME/bin/clojure
腳本。原來這個腳本是用來運行java clojure.main
的:沒有參數則進入REPL
;不然將參數做爲腳本文件名逐個執行。如今我但願用lein repl
代替它,步驟以下:函數
$HOME/.lein/profiles.clj
中添加exec-plugin
,用於將.clj
文件做爲腳本執行 {:user {:plugins [lein-exec "0.3.6"]}}
$HOME/.lein/repl
中新建工程(lein new me.zzp/repl
),用於執行lein repl
,project.clj
以下 (defproject me.zzp/repl "1.0.0" :description "Global Clojure REPL" :dependencies [[org.clojure/clojure "1.8.0"] [alembic "0.3.2"]] :main ^:skip-aot me.zzp.repl)
me.zzp.repl
中添加一些自定義的函數或宏: (ns me.zzp.repl (:require alembic.still)) (defmacro dep [& args] `(alembic.still/distill '[~@args])) (defn -main [& args])
$HOME/bin/clojure
腳本 #!/bin/sh if [ $# -eq 0 ]; then cd "$HOME/.lein/repl" exec lein repl else exec lein exec "$@" fi