Clojure:在REPL上实现一个简单的shell(一)

REPL是一个Clojure环境,它不能直接调用命令行/shell里面的命令,现在我们想在REPL里面实现一个shell,让它既可以像在shell里面直接对系统(或shell的内置命令)进行调用,也可以做REPL下能做的事情。


上一篇中我们写了一个read程序,这个程序会要求用户输入,并将获得的输入作为一个字符串来返回:

(defn ask
  "Ask for an input."
  ([] (ask "Please Input"))
  ([^String prompt]
    (printf "%s: " prompt)
    (flush)
    (.readLine *in*)))

有了这个函数,我们就可以装模做样地让REPL看起来像一个shell:

(defn shell[]
  (let [prompt "shell->"
        exit-cmd "let me out!"]
    (loop [cmd (ask prompt)]
      (if (= cmd exit-cmd)
        (println "get out!")
        (do 
          (exec cmd)
          (recur (ask prompt)))))))

我们先假设其中的”exec“函数已经存在,定义好了这两个函数之后,直接在REPL里面调用”(shell)"就可以看到类似于以下的画面:

#'user/shell
user=> (shell)
shell->: testing
you said: testing
shell->: I want money
you said: I want money
shell->: oh....
you said: oh....
shell->: let me out!
get out!
nil
user=>

这里的"shell“函数我仅仅是用了println来代替里面的exec,整个函数现在看起来就像个应声虫,也许改名为echo会适当一些——但这都仅仅是因为我们还没实现”exec“函数而已。

当然我们这个shell天生有一个缺陷,就是只能读入一行的输入,这跟REPL不一样,在REPL里面如果被判断为未完成输入的话会一直等待输入结束(例如,必须有匹配的闭括号)。关于这个问题,我们后面也许会探讨出解决方法。

至于exec的实现,请读者自行实现,或者有缘的话,让我们期待下一篇……


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值