Can someone please see what's wrong with this.

(defn getArg [arg]
        "Return a [keyword value] depending on the form of the string arg:
        1. arg is of the form +x ==> [:x true].
        2. arg is of the form -x ==> [:x false].
        3. arg is of the form x=v ==> [:x v].
        4. else ==> [:files arg]."
        (let [x (or
                   (re-seq #"([+])([a-zA-Z_0-9]+)" arg)
                   (re-seq #"([-])([a-zA-Z_0-9]+)" arg)
                   (re-seq #"([a-zA-Z_0-9]+)=([^ ]+)" arg))]
                (if (nil? x) [:files arg]
                        (let [x (first x)
                                y (nth x 1)
                                z (nth x 2)]
                                (cond
                                        (= y "+")       [(keyword z) true]
                                        (= y "-")       [(keyword z) false]
                                        :else           [(keyword y) z])))))

This is part of a command-line-arg processing function. I want to end
up with a map containing things like this:

{:verbose true :fast false :configFile "/tom/dick" :files ["foo" "bar"
"zot"]}

as a result of processing the command line args:

+verbose -fast configFile=/tom/dick foo bar zot

Now...

(getArg "+foo") correctly returns [:foo true]

however

(getArg "-foo") throws a NullPointerException.

Am I wrong in my understanding of the or function? That is, that (or a
b c) should return the first of a,b,c that returns true (i.e. non-nil)
or nil if they are all nil?

Or is something happening to the function 'arg' inside the let?


Thanks in advance.

---------------------------------------
In case it's interesting to anyone, the other part of this (that calls
getArg) is the following.

(defn getArgs [args & xs]
        "This processes args (a seq of strings) and returns a map.
        The parameter xs is a seq of two-element vectors: [keyword value].
        The returned map contains (keyword,value) pairs produced by
processing the args, as follows.
        1. An arg of the form +x creates the pair (:x true).
        2. An arg of the form -x creates the pair (:x false).
        3. An arg of the form x=v creates the pair (:x v), where v is a
string.
        4. Any other args will be placed in the pair (:files
vectorOfStrings).
        5. Any [x v] in xs, not found in the args, will create the pair (:x
v)."
        (let [res {:files []}]
                ; First process the args (if any).
                (when args (doall (for [arg args]
                        (let [ga (getArg arg) [key val] ga]
                                (cond
                                        (= key :files) (conj (:files res) val)
                                        :else          (conj res ga))))))
                ; Now process the xs (if any).
                (when xs (doall (for [x xs]
                        (let [key (first x)]
                                (when (not (key res)) (conj res x))))))
                res))

so that (for example)

(def cmdArgs (getArgs *command-line-args* [[:verbose false] [:fast
true] [:configFile "/tom/harry"] [:something "someValue"]]))

both gets command line params into the map cmdArgs and/or creates
entries with default values. What is does NOT do is validate the
parameters.
--~--~---------~--~----~------------~-------~--~----~
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 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to