views:

1983

answers:

2

I just started w/ Clojure (coming from Ruby) and I would like to build an small app with a command-line interface. How do I handle input/output to a CL?

I noticed that there is a clojure.contrib.command-line, but documentation is slim.

http://github.com/richhickey/clojure-contrib/blob/ffa868411cda6c617105b52b4f6f9e0f37ee8c24/src/clojure/contrib/command%5Fline.clj

+44  A: 

Here is an example of using with-command-line. The following code specifies a trivial class with a main method that does nothing but print out the values of its command line arguments.

(ns cmd-line-demo
  (:gen-class)
  (:use clojure.contrib.command-line))

(defn -main [& args]
  (with-command-line args
      "Command line demo"
      [[foo "This is the description for foo" 1]
       [bar "This is the description for bar" 2]
       [boolean? b? "This is a boolean flag."]
       remaining]
    (println "foo: " foo)
    (println "bar: " bar)
    (println "boolean?: " boolean?)
    (println "remaining: " remaining)))

Compile the class at the REPL:

user> (compile 'cmd-line-demo)
cmd-line-demo

Example usage

1) Executing with no command line arguments will cause the help info to be displayed. The help info can also be displayed with --help or -h flags. Note that the help info is automatically generated from your cmdspec.

$ java -classpath . cmd_line_demo
Command line demo
Options
  --foo <arg>    This is the description for foo  [default 1]
  --bar <arg>    This is the description for bar  [default 2]
  --boolean, -b  This is a boolean flag.

2) Unspecified arguments receive the default value as specified in the cmdspec binding. For example, bar has a default value of 2.

$ java -classpath . cmd_line_demo --foo "changed value"
foo:  changed value
bar:  2
boolean?:  nil
remaining:  []

3) Boolean flags are denoted by the suffix "?" in the cmdspec. Note that the flag itself does not include the "?" as part of its name.

$ java -classpath . cmd_line_demo -boolean
foo:  1
bar:  2
boolean?:  true
remaining:  []

4) Also note that you may specify flag aliases by specifying multiple symbols in the cmdspec. I have done this with the boolean? and b? flags.

5) Finally, I've specified that remaining capture all remaining arguments without associated flags.

$ java -classpath . cmd_line_demo -foo test file1 file2 file3
foo:  test
bar:  2
boolean?:  nil
remaining:  [file1 file2 file3]
alanlcode
Awesome that was exactly what I was looking for. Very thorough.I hope this ranks well on Google :)
dMix
This is indeed the most awesome example of this in existence.
Alex Miller
+3  A: 

I'd like to add that you can do

(apply -main *command-line-args*)

below the (def -main) to make it work in interpreted mode.

Pepijn