2012-03-17 13 views
7

के साथ जावा बीन्स उत्पन्न करता है क्या क्लोजर में वेक्टर दिए जाने वाले जावा बीन्स आसानी से उत्पन्न करने का कोई तरीका है? उदाहरण के लिए इस तरह एक वेक्टर दिया:क्लोजर

[ 
    String :key1 
    Integer :key2 
] 

मैं इसे करना चाहते हैं इस तरह कोड उत्पन्न करने के लिए:

public class NotSureWhatTheTypeWouldBeHere { 
    private String key1; 
    private Integer key2; 

    public NotSureWhatTheTypeWouldBeHere() {} 
    public NotSureWhatTheTypeWouldBeHere(String key1, Integer key2) { 
     this.key1 = key1; 
     this.key2 = key2; 
    } 

    public void setKey1(String key1) { 
     this.key1 = key1; 
    } 
    public String getKey1() { 
     return this.key1; 
    } 
    public void setKey2(Integer key2) { 
     this.key2 = key2; 
    } 
    public String getKey2() { 
     return this.key2; 
    } 

    // and equals,hashCode, toString, etc. 
} 

संदर्भ के लिए, मैं एक ऐप्लिकेशन है जो जावा में लिखा है लिखने के लिए चाहते हैं, लेकिन क्लोजर में लिखी लाइब्रेरी में कॉल करता है। तो इसका मतलब है कि वापसी मूल्य जावा बीन्स होना चाहिए (मुझे पता है कि उन्हें होना जरूरी नहीं है, लेकिन मैं उन्हें बनना चाहता हूं)। एक तरीका जावा में मॉडल को परिभाषित करना होगा और फिर क्लोजर कोड में मॉडल को पॉप्युलेट करने के लिए क्लोजर के सामान्य जावा इंटरऑप का उपयोग करना होगा, लेकिन मुझे एक संक्षिप्त क्लोजर वेक्टर (या मानचित्र) का विचार (वर्बोज़) जावा बीन में विस्तारित करना पसंद है।

उत्तर

3

मुझे नहीं लगता कि आपका जावा कोड स्वत: जेनरेट किए गए जावा बीन अनुपालन वर्गों के साथ अच्छी तरह से खेलेंगे। क्लोजर वापस आने के बारे में कोई समझने के लिए आप को की आवश्यकता है ताकि जावा पक्ष पर कम से कम एक इंटरफ़ेस हो।

Object result = callClojureLib(params); 

फिर, कोई फर्क नहीं पड़ता अगर वास्तविक परिणाम जावा सेम अनुबंध को लागू करता है, अपने जावा कोड भी एक कॉल करने के लिए सक्षम होने के लिए प्रतिबिंब wizardry के सभी प्रकार करना होगा: कि बिना, आप करने के लिए वापस करना होगा सेटर, क्योंकि आप कक्षा विनिर्देश खो रहे हैं।

समस्या का एक और दृष्टिकोण java.util.Map इंटरफ़ेस का उपयोग जावा और क्लोजर दुनिया के बीच अनुबंध के रूप में करना होगा।इस तरह, आप सिर्फ सादा Clojure नक्शे हस्तांतरण वस्तुओं के रूप में, इस्तेमाल कर सकते हैं के रूप में वे java.util.Map को आबंटित कर रहे हैं:

user=> (isa? (class {}) java.util.Map) 
true 
+0

+1। मैं स्ट्रिंग्स को चाबियों के रूप में उपयोग करने का सुझाव दूंगा: ये काम क्लोजर साइड पर कीवर्ड के साथ-साथ काम करते हैं लेकिन जावा एपीआई उपयोगकर्ताओं के लिए बहुत आसान है .... – mikera

+0

यह शायद सही जवाब है, लेकिन यह इस बात को याद करता है कि मैं विशेष रूप से जावा पक्ष पर एक नक्शा नहीं चाहते हैं। मेरे पास जावा कोड का एक विशाल स्वार्थ है जो सेवा, दाओ और मॉडल ऑब्जेक्ट्स का एक गुच्छा है। मैं उम्मीद कर रहा था कि मैं क्लोजर में फिर से लिख सकता हूं कि मॉडल ऑब्जेक्ट्स गतिशील रूप से जेनरेट किए जा सकते हैं (इस प्रकार कोड आकार को बड़े पैमाने पर कम कर सकते हैं)। और एक ग्राहक परिप्रेक्ष्य से, कोड मूल जावा कोड से अलग नहीं है। – Kevin

+0

मेरा सुझाव है कि आप क्लाइंट जावा कोड के नमूने से शुरू करें, जैसा कि आप चाहते हैं, और फिर एक सामान्य इंटरफ़ेस ढूंढने का प्रयास करें जो आपको आवश्यक सभी मामलों का वर्णन कर सकता है और आप क्लोजर से 'पुनः प्राप्त कर सकते हैं'। समस्या वास्तव में जावा पक्ष के साथ एक आम अनुबंध के बिना फ्लाई पर जावा बीन्स उत्पन्न करने की कोशिश कर रही है। – skuro

0

मुझे लगता है कि यह संभव होना चाहिए, लेकिन मुझे यकीन नहीं है कि आप क्लोजर में पूरी तरह से कुंजी समझते हैं (यह हो सकता है कि मैं आपका उदाहरण कोड गलत तरीके से पढ़ रहा हूं)। इस तरह के :name रूप

कुंजी प्रकार clojure.lang.Keyword, नहीं String या Integer आदि (यह भी आप सामान्य रूप से प्रकार की घोषणा नहीं करते Clojure में) के हैं। वे अक्सर मानों को पुनर्प्राप्त करने के लिए नक्शे (जो {} वाक्यविन्यास का उपयोग करते हैं) में उपयोग किए जाते हैं, उदाहरण के लिए निम्नलिखित कोड {:key1 "hello", :key2 4} मानचित्र से :key2 से जुड़े मान को पुनर्प्राप्त करता है।

(get {:key1 "hello", :key2 4} :key2) 
4 

मुझे यकीन है कि अगर आपके उदाहरण आप :key1 एक Stringमूल्य और :key2 एक Integerमूल्य के साथ जुड़े के साथ जुड़े है या अगर आपको लगता है :key1 प्रकार String की है कहने की कोशिश कर रहा है नहीं कर रहा हूँ। यदि पूर्व, शायद वेक्टर के बजाय मानचित्र का उपयोग करना चाहते हैं।

मुझे डर है मुझे नहीं लगता कि मुझे लगता है कि मैं जावा बीन्स या आपके उपयोग के मामले के बारे में काफी कुछ जानता हूं ताकि विशेष रूप से और मदद मिल सके।

2

सही से दूर और जब आप इसे उपयोग करने का प्रयास यह शायद अप्रत्याशित मुद्दों का एक बहुत कुछ है, लेकिन मुझे लगता है कि

Foo f = new Foo(); 
    f.setBaz("hithere"); 
    f.setBar(12); 
    System.out.println("f = " + f); 
    Foo f2 = new Foo(); 
    System.out.println("f2.equals(f) = " + f2.equals(f)); 
    f2.setBaz("hithere"); 
    f2.setBar(12); 
    System.out.println("f2.equals(f) = " + f2.equals(f)); 
    System.out.println("(f2.hashCode() == f.hashCode()) = " + (f2.hashCode() == f.hashCode())); 

का उत्पादन: जावा की ओर से इसका इस्तेमाल करते हुए

(ns genbean) 

    (defn -init [] 
    [[] (atom {})]) 

    (defn -toString 
    [this] 
    (str @(.state this))) 

    (defn -equals 
    [this other] 
    (= @(.state this) @(.state other))) 

    (defn -hashCode 
    [this] 
    (hash @(.state this))) 

    (defn set-field 
    [this key value] 
    (swap! (.state this) into {key value})) 

    (defn get-field 
    [this key] 
    (@(.state this) key)) 

    (defn gen-method-defs [fields] 
    (mapcat (fn [[name type]] [[(str "set" name) [type] 'void] 
          [(str "get" name) [] type]]) fields)) 

    (defn def-access-methods [fields] 
    (mapcat (fn [field] [`(defgetter ~field) `(defsetter ~field)]) fields)) 

    (defmacro defsetter [field] 
    `(defn ~(symbol (str "-set" field)) [this# value#] 
     (set-field this# ~(keyword field) value#))) 

    (defmacro defgetter [field] 
    `(defn ~(symbol (str "-get" field)) 
     [this#] 
     (get-field this# ~(keyword field)))) 

    (defmacro defbean [bean fields] 
    `(do 
     (gen-class 
      :main false 
      :state ~'state 
      :init ~'init 
      :name ~bean 
      :methods ~(gen-method-defs fields)) 
     [email protected](def-access-methods (keys fields)) 
     )) 

    (defbean com.test.Foo {Bar Integer Baz String What int}) 

: आप की तरह कुछ के साथ शुरू कर सकते हैं

f = {:Baz "hithere", :Bar 12} 
f2.equals(f) = false 
f2.equals(f) = true 
(f2.hashCode() == f.hashCode()) = true 

ध्यान दें कि आपको जैनबीन नेमस्पेस को संकलित करने की आवश्यकता होगी। कार्यान्वयन सभी गुणों को स्टोर करने के लिए एक परमाणु का उपयोग करता है, इसलिए सुनिश्चित करें कि आप व्यापार-बंद समझते हैं।

इसके अलावा, क्लोजर में काम करते समय, आप संभवतः जावबीन के साथ काम नहीं करना चाहते हैं, लेकिन आप राज्य को पकड़ने वाले परमाणु को पाने और सेट करने के लिए कुछ तरीके तैयार कर सकते हैं। इंटरफेस क्लास के रूप में java.util.Map का उपयोग करने के लिए