2012-07-10 14 views
5

के साथ क्लोजर से इंटरऑप मैं जावा क्लास के साथ क्लोजर में काम कर रहा हूं जो रिकॉर्ड की एक श्रृंखला वाले डोमेन विशिष्ट बाइनरी फ़ाइल के लिए पुनर्प्राप्ति API प्रदान करता है।गैर-मानक पुनरावर्तक जावा एपीआई

जावा वर्ग एक फ़ाइल के साथ आरंभ नहीं हो जाता और फिर, एक .query विधि है जो एक आंतरिक वर्ग जो केवल एक ही विधि .next है का एक उदाहरण देता है प्रदान करता है, इस प्रकार सामान्य जावा संग्रह एपीआई के साथ अच्छी तरह नहीं खेल। न तो बाहरी और न ही आंतरिक वर्ग किसी भी इंटरफ़ेस को लागू करता है।

.query विधि आंतरिक कक्षा के बजाय शून्य वापस आ सकती है। .next विधि कोई रिकॉर्ड स्ट्रिंग या शून्य नहीं देता है यदि कोई और रिकॉर्ड नहीं मिलता है, तो यह पहले कॉल पर तुरंत शून्य हो सकता है।

मैं इस जावा एपीआई को और जावा क्लास लिखने के बिना क्लोजर के भीतर से कैसे काम करूं?

सबसे अच्छा मैं के साथ आ सकता है:


(defn get-records 
    [file query-params] 
    (let [tr (JavaCustomFileReader. file)] 
    (if-let [inner-iter (.query tr query-params)] ; .query may return null                
     (loop [it inner-iter 
      results []] 
     (if-let [record (.next it)] 
     (recur it (conj results record)) 
     results)) 
     []))) 

यह मैं परिणामों का एक वेक्टर clojure seq कपोल-कल्पना के साथ काम करने देता है। जावा एपीआई से सीक का पर्दाफाश करने के अन्य तरीके हैं, या तो आलसी-सीक या प्रोटोकॉल का उपयोग कर?

+0

यह एक दिलचस्प सवाल है, लेकिन गैर-मानक जावा एपीआई द्वारा आपका क्या मतलब है? – octopusgrabbus

+0

@ ऑक्टोपसग्राबस विशेष रूप से मेरा मतलब है कि जावा कोड java.util.Iterator प्रदान नहीं करता है और न ही java.lang.Iterable लागू करता है। तार्किक रूप से जावा कोड पुनरावृत्ति प्रदान कर रहा है लेकिन ऐसा करने के लिए मानक एपीआई के कनेक्शन के बिना। –

उत्तर

4

lazy-seq को छोड़ने के बिना:

(defn record-seq 
    [q] 
    (take-while (complement nil?) (repeatedly #(.next q)))) 

इसके बजाय (complement nil?) की आप भी सिर्फ identity अगर .next बूलियन false वापस नहीं करता है इस्तेमाल कर सकते हैं।

(defn record-seq 
    [q] 
    (take-while identity (repeatedly #(.next q)))) 

मैं प्रविष्टि बिंदुओं को थोड़ा सा पुनर्गठन भी करता हूं।

(defn query 
    [rdr params] 
    (when-let [q (.query rdr params)] 
    (record-seq q))) 

(defn query-file 
    [file params] 
    (with-open [rdr (JavaCustomFileReader. file)] 
    (doall (query rdr params)))) 
+0

अच्छा समाधान! – Gert

4

आपका कोड आलसी नहीं है क्योंकि यह होगा यदि आप इटरटेबल का उपयोग कर रहे थे लेकिन आप निम्नानुसार आलसी-सीक के साथ अंतर को भर सकते हैं।

(defn query-seq [q] 
    (lazy-seq 
    (when-let [val (.next q)] 
     (cons val (query-seq q))))) 

हो सकता है कि आप पहले शून्य मूल्य से स्वयं को बचाने के लिए क्वेरी विधि को लपेटें।

+2

'कब-लेट' के आस-पास 'आलसी-सीक' को ऊपर ले जाएं। –

4

lazy-seq के लिए बिल्कुल उपयुक्त की तरह लगता है:

(defn query [file query] 
    (.query (JavaCustomFileReader. file) query)) 

(defn record-seq [query] 
    (when query 
    (when-let [v (.next query)] 
     (cons v (lazy-seq (record-seq query)))))) 

;; usage: 
(record-seq (query "filename" "query params")) 
संबंधित मुद्दे