Computer >> कंप्यूटर ट्यूटोरियल >  >> प्रोग्रामिंग >> Ruby

Ruby Hashes में महारत हासिल करें: उन्नत तकनीकें और छिपी हुई विशेषताएं

जब आप किसी चीज़ का उतना ही उपयोग करते हैं जितना Ruby डेवलपर्स Hashes का करते हैं, तो यह सोचना आसान है कि आपने यह सब देख लिया है।

लेकिन मैं आपको बताने आया हूँ कि विनम्र Ruby Hash की आस्तीन में कुछ तरकीबें हैं। एक मूर्ख कुंजी-मूल्य प्रणाली होने से दूर, Hash ऑब्जेक्ट आपको कुछ बहुत दिलचस्प और परिष्कृत चीजें करने की शक्ति देता है।

कोई भी ऑब्जेक्ट हैश कुंजी हो सकता है

इससे पहले कि हम आगे बढ़ें, मैं एक बात बताना चाहूँगा जो स्पष्ट नहीं हो सकती। जबकि हम स्ट्रिंग्स और सिंबल को हैश कुंजी के रूप में उपयोग करते हैं, इसका मतलब यह नहीं है कि हम अन्य प्रकार के ऑब्जेक्ट्स का उपयोग नहीं कर सकते। वास्तव में, आप लगभग किसी भी चीज़ को हैश कुंजी के रूप में उपयोग कर सकते हैं।

# संख्याएं हैश कुंजी हो सकती हैं {1 => "one"}[1] # "one" # Ruby कर्नेल भी हो सकता है {Kernel => 1}[Kernel] # 1 # आप विशिष्ट वर्गों के लिए मान संग्रहीत कर सकते हैं {Kernel => 1, String => 2}["hello world".class] # 2 # आप बूलियन के लिए मान संग्रहीत कर सकते हैं {true => "verdad"}[1==1] # "verdad" # आप जटिल सरणियों और यहां तक कि अन्य हैश को भी हैश कुंजी के रूप में उपयोग कर सकते हैं {[[1,0],[0,1]] => "identity matrix"}[[[1,0], [0,1]]] # "identity matrix" 

इनमें से कुछ विकल्प दूसरों की तुलना में अधिक उपयोगी हैं, लेकिन वे सभी आपके लिए उपलब्ध हैं।

आपके पास डिफ़ॉल्ट मान पर नियंत्रण है

मान लीजिए आपके पास एक हैश `h={ a: 1 }` है। यदि आप किसी ऐसे मान को एक्सेस करने का प्रयास करते हैं जो मौजूद नहीं है - उदाहरण के लिए `h[:x]` - तो आपको nil मिलता है। ऐसा इसलिए है क्योंकि nil हर हैश का डिफ़ॉल्ट मान है, जब तक कि आप अन्यथा निर्दिष्ट न करें।

आप कंस्ट्रक्टर में एक आर्गुमेंट पास करके नए हैश के लिए डिफ़ॉल्ट मान सेट कर सकते हैं।

h = Hash.new("This attribute intentionally left blank") h[:a] = 1 h[:a] # 1 h[:x] # "This attribute intentionally left blank" 

डायनामिक डिफ़ॉल्ट मान

ध्यान दें, क्योंकि यह ट्रिक उन सभी चीजों की नींव है जो आगे आती हैं।

यदि आप कंस्ट्रक्टर में एक ब्लॉक पास करते हैं, तो आप प्रोग्रामेटिक रूप से डिफ़ॉल्ट मान उत्पन्न कर सकते हैं। नीचे दिए गए उदाहरण में मैंने डिफ़ॉल्ट मान में एक टाइमस्टैम्प जोड़ा है, ताकि आप देख सकें कि यह डायनामिक रूप से उत्पन्न हो रहा है।

h = Hash.new { |hash, key| "#{key}: #{ Time.now.to_i }" } h[:a] # "a: 1435682937" h[:a] # "a: 1435682941" h[:b] # "b: 1435682943" 

यह महत्वपूर्ण है क्योंकि "डिफ़ॉल्ट मान" ब्लॉक डिफ़ॉल्ट मान वापस करने के अलावा अन्य चीजें कर सकता है।

यदि हैश कुंजी मौजूद नहीं है तो अपवाद उठाना

हैश के साथ मुख्य समस्याओं में से एक यह है कि वे चुपचाप विफल होते हैं। आप गलती से `user[:phnoe]` टाइप करते हैं `user[:phone]` के बजाय, और अपवाद उठाने के बजाय, हैश nil लौटाता है। लेकिन आप इस व्यवहार को बदल सकते हैं।

h = Hash.new { |hash, key| raise ArgumentError.new("No hash key: #{ key }") } h[:a]=1 h[:a] # 1 h[:x] # ArgumentError उठाता है: No hash key: x 

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

नोट: मैं यह सुझाव नहीं दे रहा हूँ कि कोई नए कोड में Hash.fetch के स्थान पर इसका उपयोग करे। यह सिर्फ डिबगिंग और रीफैक्टरिंग के लिए अपनी आस्तीन में रखने के लिए एक दिलचस्प ट्रिक है।

आलसी-जनित लुकअप टेबल

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

sqrt_lookup = Hash.new { |hash, key| hash[key] = Math.sqrt(key) } sqrt_lookup[9] # 3.0 sqrt_lookup[7] # 2.6457513110645907 sqrt_lookup # {9=>3.0, 7=>2.6457513110645907} 

पुनरावर्ती आलसी लुकअप टेबल

मान लीजिए आपके पास एक पुनरावर्ती फ़ंक्शन है और आप प्रत्येक पुनरावृत्ति के परिणाम को कैश करना चाहते हैं। आइए फैक्टोरियल गणना को एक उदाहरण के रूप में लें। "चार फैक्टोरियल", उर्फ "4!" बस "4x3x2x1" कहने का दूसरा तरीका है। आप इसे हैश का उपयोग करके पुनरावर्ती रूप से लागू कर सकते हैं। नीचे दिया गया उदाहरण, जिसे मैंने इस ब्लॉग पोस्ट से लिया है, इसे अच्छी तरह से प्रदर्शित करता है:

factorial = Hash.new do |h,k| if k > 1 h[k] = h[k-1] * k else h[k] = 1 end end factorial[4] # 24 factorial # {1=>1, 2=>2, 3=>6, 4=>24} 

आरंभीकरण के बाद डिफ़ॉल्ट मान संशोधित करना

आप हैश बनने के बाद भी डिफ़ॉल्ट मान को नियंत्रित कर सकते हैं। ऐसा करने के लिए `default` और `default_proc` सेटर्स का उपयोग करें।

h={} h[:a] # nil h.default = "new default" h[:a] # "new default" h.default_proc = Proc.new { Time.now.to_i } h[:a] # 1435684014 

रूबी खोजें: आलसी अनंत नेस्टेड हैश का खेल

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

कल्पना करें कि आप एक गुफा में हैं। आप उत्तर, दक्षिण, पूर्व या पश्चिम जा सकते हैं। इनमें से तीन विकल्प आपको गुफा के एक नए "कमरे" में ले जाते हैं जहां आप खोज जारी रखते हैं। लेकिन एक विकल्प आपको "रूबी" तक ले जाता है। इसलिए खेल का नाम: "रूबी खोजें।"

गुफा में प्रत्येक कमरा एक हैश से मेल खाता है। हैश में केवल एक एंट्री होती है। `["n", "s", "e", "w"]` में से एक, जिसे यादृच्छिक रूप से चुना जाता है, का मान "You found the ruby." होता है। यदि आप गलत चुनते हैं तो एक नया हैश बनाया जाता है और ट्री में जोड़ा जाता है।

generator = Proc.new do |hash, key| hash[key] = Hash.new(&generator).merge(["n", "s", "e", "w"][rand(4)] => "You found the ruby!") end dungeon = Hash.new(&generator) dungeon["n"] # <Hash ... dungeon["n"]["s"] # <Hash ... dungeon["n"]["s"]["w"] # "You found the ruby!" 

  1. Ruby में Lambdas में महारत हासिल करें: बुनियादी से उन्नत तकनीकें तक Ruby में Lambdas में महारत हासिल करें: बुनियादी से उन्नत तकनीकें तक

    ब्लॉक Ruby का इतना महत्वपूर्ण हिस्सा हैं, उनके बिना भाषा की कल्पना करना कठिन है। लेकिन लैम्ब्डा? कौन लैम्ब्डा से प्यार करता है? आप वर्षों तक बिना एक का उपयोग किए जा सकते हैं। वे लगभग एक बीते युग के अवशेष लगते हैं। ...लेकिन यह पूरी तरह सच नहीं है। लैम्ब्डा की आस्तीन में कुछ दिलचस्प तरकीबें हैं एक बार

  1. Ruby 2.6 में 9 प्रमुख संवर्द्धन का अन्वेषण Ruby 2.6 में 9 प्रमुख संवर्द्धन का अन्वेषण

    Ruby का एक नया संस्करण नई सुविधाओं और प्रदर्शन सुधारों के साथ आ रहा है। क्या आप परिवर्तनों के साथ बने रहना चाहेंगे? आइए एक नज़र डालते हैं! अंतहीन रेंज (Endless Ranges) Ruby 2.5 और पुराने संस्करण पहले से ही अंतहीन रेंज का एक रूप (Float::INFINITY के साथ) का समर्थन करते हैं, लेकिन Ruby 2.6 इसे अगले स्त

  1. हैश टेबल्स की व्याख्या हैश टेबल्स की व्याख्या

    मेरी पसंदीदा डेटा संरचनाओं में से एक हैश तालिका है क्योंकि यह सरल और शक्तिशाली है। आपने शायद पहले इसका इस्तेमाल किया होगा क्योंकि यह की-वैल्यू पेयर को स्टोर करने का एक कारगर तरीका है। हैश तालिका के कार्यान्वयन के पीछे कुछ दिलचस्प कंप्यूटर विज्ञान अवधारणाएँ हैं जो अध्ययन के लायक हैं, और ठीक यही हम