2009-11-30 11 views
12

ठीक है, इसलिए मैं एक हैश बनाना चाहता था जिसमें डिफ़ॉल्ट हैश के रूप में एक खाली हैश है। थोड़ा अजीब, मुझे पता है, लेकिन मान लें कि मैंने सोचा कि यह उपयोगी हो सकता है।हैश.न्यू ({}) हैश सदस्यों को क्यों छुपाता है?

तो यहाँ मैं क्या किया है:

>> a = Hash.new({}) 
=> {} 
>> a[:a][:b] = 5 
=> 5 
>> a 
=> {} 
>> a[:a] 
=> {:b=>5} 
>> a.keys 
=> [] 
>> a.size 
=> 0 
>> a[:a].size 
=> 1 

दूसरे शब्दों में, मैं हैश सदस्य जब मैं हैश का निरीक्षण नहीं दिख रहा है, लेकिन मैं उसके प्रमुख तक पहुँच सकते हैं।

क्या यह अपेक्षित व्यवहार है? यहाँ क्या हो रहा है?

बीटीडब्ल्यू, यह रूबी 1.9.1 है, पिछले संस्करणों की कोशिश नहीं की है।

संपादित करें: सरलीकृत उदाहरण के रूप में यह हैश के हैश का एक हैश होने के लिए नहीं है ...

+0

भी 1.8.7 पर पुन: उत्पादित। –

उत्तर

17

यह व्यवहार (सभी माणिक संस्करणों में) की उम्मीद है। और अगर आप थोड़ा आगे प्रयोग, आपको लगता है कि आप हमेशा एक ही हैश का उपयोग देखेंगे, कोई फर्क नहीं पड़ता कि आप का उपयोग जो कुंजी:

>> a[:a][:b] = 1 
=> 1 
>> a[:c][:d] = 2 
=> 2 
>> a[:d] 
=> {:b=>1, :d=>2} 

एक डिफ़ॉल्ट तर्क के साथ जिस तरह से Hash.new काम करता है: आप hash[key] करते हैं यह जांचता है कि हैश में वह कुंजी मौजूद है या नहीं। यदि ऐसा होता है, तो वह उस कुंजी के लिए मान देता है। यदि नहीं, तो यह डिफ़ॉल्ट मान देता है। यह हैश की कुंजी नहीं जोड़ता है और यह हर बार एक ही डिफ़ॉल्ट वस्तु (प्रतिलिपि नहीं) वापस करेगा।

आप जो चाहते हैं उसे प्राप्त करने के लिए, आप इसके बजाय एक डिफ़ॉल्ट ब्लॉक निर्दिष्ट करना चाहते हैं। इस तरह, हर बार जब आप हैश में नहीं है तो ब्लॉक को निष्पादित किया जाएगा। ब्लॉक के अंदर आप एक नया हैश बना सकते हैं और उस हैश पर "पॉइंट" की कुंजी सेट कर सकते हैं। इस तरह:

Hash.new { |h,k| h[k] = {} } 
+0

तो मूल रूप से, उन्होंने कुंजी को डिफ़ॉल्ट मान पर जोड़ा, न कि उसके हैश। – Riking

संबंधित मुद्दे