生活在REPL中(续):在REPL中动态加载依赖的库

在之前的文章《生活在REPL中:工具与程序一体》中,我描绘了把Clojure REPL当做SHELL来使用的场景,在REPL中做诸如访问数据库、加解密等日常开发工作。

但使用REPL中最郁闷的就是依赖的类库无法动态加载。例如代码运行到一半,忽然发现需要解析JSON字符串,不得不退出REPL,在project.clj中添加依赖的JSON解析包,然后重新进入REPL并敲一堆代码恢复到之前退出的场景。这一方面Clojure或者说Java无法做到像SHELL那样简便地修改PATH环境变量一样修改CLASSPATH,以实现动态加载类库的目的。

今天终于下决心解决这个问题,并且我相信肯定已经有解决方案了!网络上搜索了半天,终于在一篇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
    

转载于:https://my.oschina.net/redraiment/blog/661272

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值