Hi, I really like cli4j and have a nice pattern I follow in creating CLI entry points for my project. I find it has a lot of advantages, including a declarative means of defining your CLI syntax using annotations.
So I thought it might be nice not to have to write all new interface wrappers to gain access to these command-oriented interfaces from a REPL context. It turned out to be remarkably easy to do this, and I thought I'd pass on my experience. It should be entirely applicable even for those not using cli4j. Here's what I did: 1) Wrote a few helper functions to allow keywords such as :o or :option to stand in for "-o" or "--option" arguments. There are three variants (at least conceptually), to produce A) a list; B) a vector and C) a String[] holding the converted arguments. To wit: (defn make-cli-arglist "Create a list of strings encoding a CLI invocation from a sequence of keywords and other (atomic) values" [args] (map #(if (keyword? %) (let [opt-name (name %)] (if (> (.length opt-name) 1) (str "--" opt-name) (str \- opt-name))) (str %)) args)) (defn make-cli-argvec "Create a vector of strings encoding a CLI invocation from a sequence of keywords and other (atomic) values" [args] (apply vector (make-cli-arglist args))) (defn make-cli-argarray "Create a vector of strings encoding a CLI invocation from a sequence of keywords and other (atomic) values" [args] (into-array String (make-cli-arglist args))) 2) Wrote a top-level launcher function that converts its arguments using (1C) and calls the embedding entry point (see (3)) of the Java command-line class. 3) Wrote an alternate entry point to the Java main(String[] args) that returns its termination status rather than calling System.exit(status). (Naturally, I was both delighted and surprised when my first successful attempt dumped me out of Clojure upon completing its invocation.) 4) The last refinement I added was a macro version of (2), which means that for arguments that don't contain any characters that are special in Clojure, enclosing those arguments in quote marks is unnecessary. This is, of course, directly analogous to a similar requirement in any Unix shell. Note: This actually obviates the keyword conversion aspect of the argument list synthesizer in (1), though conversion to all String instances is still necessary, of course. The one possibly still-useful thing that code does is blur the distinction between single-character options (which use a single hyphen) and multi-character options (which use two hyphens) by automatically choosing the proper syntax for the converted option name. So far, the only visible "seam" I've noticed is that when you use the keyword-as-option mode and there's an error, the old CLI code, not ever having seen a Lisp keyword (nor having any notion of such things) prints diagnostics using hyphens. Between this approach and Steve G.'s new REPL, I feel I'm going to get an interactive environment for my full suite of tools that is independent of a Unix shell virtually for free. Other advantages of this include platform independence (I have potential users on Windows) and the elimination of the JVM start-up overhead for each individual invocation. I know this isn't barely actually Clojure programming, just an exercise of Clojure's very slick Java integration, but I found it gratifying. Randall Schulz --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~----------~----~----~----~------~----~------~--~---