2012-06-10 19 views
5

Jestem nowy w Clojure i utknąłem na tym, jak "rozwinąć" opcjonalne argumenty funkcji, aby można je było wysłać do innej funkcji, która używa opcjonalnych argumentów (ale chce tych args jako słowa kluczowe, a nie jako kolejne słowa kluczowe).Clojure: Przekaż rozszerzone opcjonalne argumenty do funkcji

mam parsowania xml i gdybym twarde wartości kodów jak poniżej moja funkcja działa, spacery xml i wyszukuje wartość „tytuł”:

; zd was required like this 
[clojure.data.zip.xml :as zd] 
; ... 
(defn get-node-value [parsed-xml & node-path] 
    (zd/xml-> (zip/xml-zip parsed-xml) :item :title zd/text)) 

(get-node-value parsed-xml) 

Co chcę zrobić jest użycie „węzeł path”przejść w dowolnej liczby słów kluczowych, ale kiedy napisane jak poniżej to jest w postaci sekwencji słów kluczowych tak zgłasza wyjątek:

(defn get-node-value [parsed-xml & node-path] 
    (zd/xml-> (zip/xml-zip parsed-xml) node-path zd/text)) 

(get-node-value parsed-xml :item :title) 
; ClassCastException clojure.lang.ArraySeq cannot be cast to clojure.lang.IFn clojure.data.zip/fixup-apply (zip.clj:73) 

dzięki!

Odpowiedz

8

myślę szukasz Zastosuj (http://clojuredocs.org/clojure_core/clojure.core/apply)

(defn get-node-value [parsed-xml & node-path] 
    (let [params (concat node-path [zd/text])] 
    (apply zd/xml-> (zip/xml-zip parsed-xml) params))) 
3

Może chcesz:

(defn get-node-value [parsed-xml & node-path] 
    (zd/xml-> (zip/xml-zip parsed-xml) ((apply comp (reverse node-path))) zd/text)) 

mogę "przetestuj powyższe, więc działam od analogii:

(-> {:a {:c 1}, :b 2} ((apply comp (reverse [:a :c])))) 
1 

Jednakże, jeśli dAni's rozwiązanie działa, ignoruj ​​mnie!