简体   繁体   English

解析Clojure命令行参数

[英]Parse Clojure Command Line Args

I am trying to separate my cli options into a stand-alone namespace for starting up an HTTP server, and I am getting this error- 我试图将cli选项分离到一个独立的命名空间中,以启动HTTP服务器,但出现此错误-

 clojure.lang.ArraySeq cannot be cast to java.lang.CharSequence

In main.clj , this code works fine- main.clj ,此代码可以正常工作-

(ns served.main
  (:require [org.httpkit.server :refer [run-server]]
    [served.app.core :refer [handler]]
    [served.server.cli-options :refer [set-options]]
    [clojure.tools.cli :refer [parse-opts]])
    (:gen-class))

(def cli-options
 [
  ["-p" "--port PORT" "Port number"
  :default 5000 
  :parse-fn #(Integer/parseInt %)
  :validate [#(< 0 % 0x10000) "Must be a number between 0 and 65536"]]
  ])  

(defn -main [& args]
  (println "Server starting")
  (let [options (get (parse-opts args cli-options) :options)]
  ;;(let [options (set-options args)]
  (println (str options))
  (run-server handler options))) 

It will work with the default options in (def cli-options) and it compiles correctly if I pass in arguments, such as -p 7000 . 它将与(def cli-options)的默认选项一起使用,并且如果我传入参数,例如-p 7000 ,它将正确编译。

When I call the main function with the external namespace served.server.cli-options instead of clojure.tools.cli directly (ie switch the comment in main ), I get the error only when passing in args. 当我使用外部命名空间served.server.cli-options而不是clojure.tools.cli直接调用main函数时(即在main切换注释),仅在传入args时才会出现错误。

That is, starting the server without arguments, eg lein run compiles fine and will print out the defaults. 也就是说,在不带参数的情况下启动服务器,例如lein run编译,并将输出默认值。 The error comes with lein run -p 7000 . 该错误来自lein run -p 7000

After deleting (def cli-options) in main to avoid any global conflict, here is served.server.cli-options main删除(def cli-options)以避免任何全局冲突之后,这里提供了served.server.cli-options

(ns served.server.cli-options
  (:require [clojure.tools.cli :refer [parse-opts]]))

(def cli-options
  [
    ["-p" "--port PORT" "Port number"
    :default 5000 
    :parse-fn #(Integer/parseInt %)
    :validate [#(< 0 % 0x10000) "Must be a number between 0 and 65536"]]
  ])  

(defn set-options [& args]
  (let [options (get (parse-opts args cli-options) :options)]
  (println (str options))  
  options))

So far as I can tell, I copied the contents to the new namespace correctly. 据我所知,我已将内容正确复制到新的名称空间。 Here are the docs for parse-opts , here is the example that I am drawing from, and a similar but different SO issue here . 下面是该文档parse-opts这里是我从图纸的例子,和类似的,但不同的SO发出这里

My question - how are the CLI args being transformed to throw casting error, and how do I fix it? 我的问题-如何将CLI args转换为引发转换错误,以及如何解决?

Any help would be greatly appreciated. 任何帮助将不胜感激。

Delete the & in: 删除&中:

(defn set-options [& args]

& wraps up any additional arguments in a seq. &将所有其他参数包装在seq中。 Since you've already wrapped the program arguments once in main , you mustn't do it again in the call to set-options . 由于您已经在main包装了一次程序参数,因此您不必在调用set-options再做一次。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM