在以前的文章《生活在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