2009-10-01 13 views
8

यहाँ माणिक में हैश autovivification सक्षम करने के लिए एक चतुर चाल (पहलुओं से लिया गया) है:माणिक हैश autovivification (पहलुओं)

# File lib/core/facets/hash/autonew.rb, line 19 
    def self.autonew(*args) 
    leet = lambda { |hsh, key| hsh[key] = new(&leet) } 
    new(*args,&leet) 
    end 

हालांकि यह (बेशक) काम करता है, मैं यह वास्तव में निराशा होती है कि लगता है मैं कर सकते हैं ' यह पता लगाने के लिए कि यह दो लाइनर यह करता है कि यह क्या करता है।

लीट को डिफ़ॉल्ट मान के रूप में रखा जाता है। तो उसके बाद h['new_key'] तक पहुंचने से यह किसी भी तरह से इसे लाता है और 'new_key' => {}

अब, मैं h['new_key'] की समीक्षा करने के विपरीत डिफ़ॉल्ट मान ऑब्जेक्ट को वापस करने की अपेक्षा करता हूं। यही है, 'new_key' => {} स्वचालित रूप से नहीं बनाया गया है। तो लीट वास्तव में कैसे बुलाया जाता है? विशेष रूप से दो मानकों के साथ?

उत्तर

18

मानक new method for Hash एक ब्लॉक स्वीकार करता है। इस ब्लॉक को हैश में एक कुंजी तक पहुंचने का प्रयास करने की स्थिति में बुलाया जाता है जो अस्तित्व में नहीं है। ब्लॉक को हैश को ही पास किया गया है और जिस कुंजी से अनुरोध किया गया था (दो पैरामीटर) और अनुरोधित कुंजी के लिए वापस लौटाए जाने वाले मान को वापस कर देना चाहिए।

आप देखेंगे कि leet लैम्ब्डा 2 चीजें करता है। यह डिफ़ॉल्ट रूप से हैंडलिंग के लिए ब्लॉक के रूप में leet के साथ एक नया हैश देता है। यह व्यवहार है जो autonew को मनमानी गहराई के हेश के लिए काम करने की अनुमति देता है। यह इस नए हैश को hsh[key] पर भी निर्दिष्ट करता है ताकि अगली बार जब आप एक ही कुंजी का अनुरोध करेंगे तो आपको एक नए बनाए जाने के बजाय मौजूदा हैश मिलेगा।

+0

उत्कृष्ट उत्तर। – Pesto

+1

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

8

यह भी ध्यान देने योग्य है इस प्रकार है कि इस कोड एक एक लाइनर में बनाया जा सकता है लायक है:

def self.autonew(*args) 
    new(*args){|hsh, key| hsh[key] = Hash.new(&hsh.default_proc) } 
end 

कॉल # default_proc हैश proc कि माता-पिता को बनाने के लिए इस्तेमाल किया गया था देता है, तो हम एक है यहाँ अच्छा recursive सेटअप।

मैं अपने ब्लॉग पर similar case के बारे में बात करता हूं।

-1

वैकल्पिक रूप से, आप मेरे xkeys gem पर विचार कर सकते हैं। यह एक मॉड्यूल है जिसका उपयोग आप नेस्टेड एक्सेस को सुविधाजनक बनाने के लिए सरणी या हैंश का विस्तार करने के लिए कर सकते हैं।

यदि आप ऐसा कुछ ढूंढते हैं जो अभी तक अस्तित्व में नहीं है, तो आपको कुछ भी न देखे बिना शून्य मूल्य (या कोई अन्य मूल्य या अपवाद अगर आप पसंद करते हैं) प्राप्त करते हैं। यह सरणी के अंत में भी संलग्न हो सकता है।

आप पूर्णांक कुंजियों के लिए या तो हैश या सरणी को स्वत: सक्रिय करने का विकल्प चुन सकते हैं (लेकिन केवल संपूर्ण संरचना के लिए)।