2008-10-16 8 views
5

उम्मीद है कि मैंने "बतख टाइपिंग" के अर्थ को गलत समझा नहीं है, लेकिन जो मैंने पढ़ा है, इसका मतलब है कि मुझे इस प्रकार के आधार पर कोड लिखना चाहिए कि किस प्रकार की वस्तु/वर्ग के बजाय तरीकों का जवाब देता है।क्या मैं इस विधि को बतख टाइपिंग के साथ सुधार सकता हूं?

def convert_hash(hash) 
    if hash.keys.all? { |k| k.is_a?(Integer) } 
    return hash 
    elsif hash.keys.all? { |k| k.is_a?(Property) } 
    new_hash = {} 
    hash.each_pair {|k,v| new_hash[k.id] = v} 
    return new_hash 
    else 
    raise "Custom attribute keys should be ID's or Property objects" 
    end 
end 

क्या मैं चाहता हूँ लगता है कि मैं एक हैश के साथ अंत जहां कुंजी एक पूर्णांक एक ActiveRecord वस्तु की आईडी का प्रतिनिधित्व कर रहे हैं बनाने के लिए है:

कोड यह रहा। मुझे विशेष रूप से हैश कुंजी के माध्यम से all? के साथ दो बार फिर से प्रयास करने का आनंद लेने का आनंद नहीं मिलता है, यह निर्धारित करने के लिए कि मुझे आईडी के बाहर ले जाने की आवश्यकता है या नहीं।

बेशक, मैं भी इस कोड को बेहतर बनाने के लिए किसी भी अन्य सुझावों को स्वीकार करेंगे :)

+0

यहाँ तक कि "बतख टाइपिंग" से पहले कभी नहीं सुना: आप कुछ इस तरह की कोशिश कर सकते। आप उस पर कहाँ आए थे? –

+0

@ ब्रायन, http://en.wikipedia.org/wiki/Duck_typing –

उत्तर

11

आप इस विधि का है कि क्या आप उम्मीद कर एक अपवाद सामान्य प्रोग्राम निष्पादन के दौरान फेंक दिया करने के लिए पर निर्भर होना चाहिए कैसे लिख सकता हूँ। यदि आप एक पठनीय अपवाद संदेश चाहते हैं क्योंकि एक अंतिम उपयोगकर्ता इसे देख सकता है, तो मैन्युअल रूप से फेंकना समझ में आता है। अन्यथा, मैं तो बस कुछ इस तरह करते हैं:

def convert(hash) 
    new_hash = {} 
    hash.each_pair { |k,v| new_hash[ k.is_a?(Integer) ? k : k.id ] = v } 
    return new_hash 
end 

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

हमारे पास अभी भी पूर्णांक वस्तुओं के लिए एक स्पष्ट जांच है, लेकिन इस तरह का कभी-कभी विशेष मामला आमतौर पर स्वीकार्य होता है, विशेष रूप से अंतर्निहित डेटा प्रकारों की जांच करते समय।

+1

कुछ बहुत रूबीश कोड, एली के साथ महान, वर्णनात्मक उत्तर। उत्तर देने के लिए बहुत बहुत धन्यवाद। –

+1

इसके साथ समस्या यह है कि रूबी में प्रत्येक ऑब्जेक्ट में #id विधि होती है। यह ऑब्जेक्ट पर परिभाषित किया गया है, और रूबी दुभाषिया में उस ऑब्जेक्ट में एक अद्वितीय संदर्भ देता है। हालांकि इसे हटा दिया गया है, इसलिए आपको चेतावनी मिलेगी, आपको अपवाद नहीं मिलेगा। – madlep

3

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

समस्या यह तथ्य है कि आप एक विधि में दो अलग-अलग डेटा संरचनाओं को स्वीकार कर रहे हैं। बतख टाइपिंग कार्य करने का तरीका यह आवश्यक है कि आपकी विधि में पारित होने वाली सभी वस्तुएं एक ही अनुबंध का पालन करें (यानी यह हमेशा [Foo] ऑब्जेक्ट्स के इंटीग्रर्स का हैश है।) संपत्ति कुंजी के साथ हैश को परिवर्तित करने की प्रक्रिया सही संरचना क्लाइंट कोड का काम होना चाहिए। यह एक साधारण रैपर वर्ग या एक रूपांतरण समारोह के साथ बहुत आसानी से किया जा सकता है जिसमें केवल आपके अन्य खंड के शरीर शामिल हैं।

नीचे की रेखा यह सुनिश्चित करने के लिए कि वह अपने तरीके से क्वाक करने की अपेक्षा करता है, उसके पैरामीटर सभी को ठीक करने के तरीके को कॉल करने वाले व्यक्ति पर निर्भर करता है। यदि वे नहीं करते हैं, तो वह वह व्यक्ति है जिसकी पहचान करने की आवश्यकता है कि उसे टर्की की तरह बतख कैसे बनाया जाए, न कि आप।

0

मैं यह सुनिश्चित करना चाहता हूं कि मैं एक हैश के साथ समाप्त हो जहां कुंजी एक ActiveRecord ऑब्जेक्ट की आईडी का प्रतिनिधित्व करने वाला एक पूर्णांक है।

आपको शायद उस के लिए जांच करनी चाहिए जब आप हैश में बना रहे/डालने वाले हैं।

 
h = {} 
def h.put obj 
    self[obj.id]=obj 
end 

या शायद

 
h = {} 
def h.[]= key, value 
    raise "hell" unless key == value.id 
    super 
end 
संबंधित मुद्दे