2013-02-22 90 views
5

के माध्यम से जावा क्लास को राउंड-ट्रिपिंग करना मेरे पास जावा क्लास Vector2 है जो मैं क्लोजर रीडर के साथ "अच्छी तरह से खेलना" के लिए राजी करना चाहता हूं।क्लोजर प्रिंटर और रीडर

(def a (vec2 1 2)) 
(print-str a) 
=> "#<Vector2 [1 2]>" 

आदर्श रूप से मैं क्लास को क्लोजर रीडर द्वारा पढ़ा जा सकने वाले फॉर्म में प्रिंट करना चाहता हूं। अर्थात मैं सच लौटने के लिए निम्नलिखित करना चाहते हैं:

(= a (read-string (print-str a))) 

इस राउंड ट्रिपिंग क्षमता को प्राप्त करने का सबसे अच्छा तरीका क्या है?

+0

आप को शामिल करने के 'EvalReader', मुझे लगता है नहीं करना चाहते? –

+0

@ मार्को: सुझावों के लिए खोलें। यह विशेष रूप से बाहरी एपीआई के लिए नहीं है - आरईपीएल और आसान क्रमबद्धता/deserialisation में सुविधा के लिए अधिक। – mikera

+0

मुझे लगता है कि 'read-eval' को सच में छोड़ दिया गया है, पाठक को पता चलेगा कि' # = (वेक्टर 2। 1 2) 'के साथ क्या करना है। –

उत्तर

5

आपको अपनी कक्षा/प्रकार के लिए print-dup और print-method multimethods प्रदान करने की आवश्यकता है।

चेक बाहर core.clj

पूर्व:

(import 'java.util.Hashtable) 
(defmethod print-method Hashtable [x writer] 
     (binding [*out* writer] 
     (print (let [h (gensym)] 
       `(let [~h (Hashtable.)] 
        [email protected](map (fn [i] 
           `(.put ~h ~(str "\"" (.getKey i) "\"") ~(.getValue i) )) x) ~h))) )) 
(def a (Hashtable.)) 
(.put a "a" 1) 
(.put a "b" 2) 
(= a (eval (read-string (print-str a)))) 
+0

ऐसा लगता है कि केवल लेखन अंत को कवर किया गया है। यह कैसे पढ़ता है? –

+0

'रीड-स्ट्रिंग' पढ़ने के लिए है। असल में यह multimethod स्ट्रिंग प्रारूप में एक एस-अभिव्यक्ति वापस करेगा जैसे '(vec2 1 2)' जब वांछित ऑब्जेक्ट – Ankur

+0

बनाने के परिणामस्वरूप निष्पादित किया गया यह मिकरा चाहता है: वह कोड को 'eval' नहीं करना चाहता उसकी वस्तु; वह ** मूल क्लोजर वेक्टर की तरह ** ** इसे पढ़ना चाहता है। –