生活在REPL中(續):在REPL中動態加載依賴的庫

在以前的文章《生活在REPL中:工具與程序一體》中,我描繪了把Clojure REPL當作SHELL來使用的場景,在REPL中作諸如訪問數據庫、加解密等平常開發工做。java

但使用REPL中最鬱悶的就是依賴的類庫沒法動態加載。例如代碼運行到一半,突然發現須要解析JSON字符串,不得不退出REPL,在project.clj中添加依賴的JSON解析包,而後從新進入REPL並敲一堆代碼恢復到以前退出的場景。這一方面Clojure或者說Java沒法作到像SHELL那樣簡便地修改PATH環境變量同樣修改CLASSPATH,以實現動態加載類庫的目的。shell

今天終於下決心解決這個問題,而且我相信確定已經有解決方案了!網絡上搜索了半天,終於在一篇StackOverflow的帖子中看到了相關的解答:使用alembic,可實現動態加載類庫的功能。具體方法以下:數據庫

  1. project.clj中引入[alembic "0.3.2"]或更高版本
  2. lein repl
  3. (require 'alembic.still)
  4. (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代替它,步驟以下:函數

  1. $HOME/.lein/profiles.clj中添加exec-plugin,用於將.clj文件做爲腳本執行
    {:user {:plugins [lein-exec "0.3.6"]}}
  2. $HOME/.lein/repl中新建工程(lein new me.zzp/repl),用於執行lein replproject.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)
  3. me.zzp.repl中添加一些自定義的函數或宏:
    (ns me.zzp.repl
      (:require alembic.still))
    
    (defmacro dep [& args]
      `(alembic.still/distill '[~@args]))
    
    (defn -main [& args])
  4. 添加$HOME/bin/clojure腳本
    #!/bin/sh
    
    if [ $# -eq 0 ]; then
        cd "$HOME/.lein/repl"
        exec lein repl
    else
        exec lein exec "$@"
    fi
相關文章
相關標籤/搜索