अपरिवर्तनीय कुंजी सामान्य रूप से समझ में आती हैं क्योंकि उनके हैश कोड स्थिर होंगे।
यही कारण है कि तार, विशेष रूप से बदल दिया जाता है एमआरआई कोड के इस हिस्से में:
if (RHASH(hash)->ntbl->type == &identhash || rb_obj_class(key) != rb_cString) {
st_insert(RHASH(hash)->ntbl, key, val);
}
else {
st_insert2(RHASH(hash)->ntbl, key, val, copy_str_key);
}
संक्षेप में, स्ट्रिंग कुंजी मामले में, st_insert2
एक समारोह के लिए एक सूचक है कि ट्रिगर किया जाएगा पारित हो जाता है डुप्लिकेट और फ्रीज।
तो अगर हम सैद्धांतिक रूप से अपरिवर्तनीय सूचियों और हैश कुंजी के रूप में अपरिवर्तनीय हैश समर्थन करना चाहते थे, तो हम उस कोड कुछ करने के लिए इस तरह संशोधित कर सकते हैं:
VALUE key_klass;
key_klass = rb_obj_class(key);
if (key_klass == rb_cArray || key_klass == rb_cHash) {
st_insert2(RHASH(hash)->ntbl, key, val, freeze_obj);
}
else if (key_klass == rb_cString) {
st_insert2(RHASH(hash)->ntbl, key, val, copy_str_key);
}
else {
st_insert(RHASH(hash)->ntbl, key, val);
}
freeze_obj
परिभाषित किए जाएँगे कहाँ के रूप में:
static st_data_t
freeze_obj(st_data_t obj)
{
return (st_data_t)rb_obj_freeze((VALUE) obj);
}
तो यह आपके द्वारा देखी गई विशिष्ट असंगतता को हल करेगा, जहां सरणी-कुंजी उत्परिवर्तनीय थी। हालांकि वास्तव में संगत होने के लिए, अधिक प्रकार की वस्तुओं को भी अपरिवर्तनीय बनाने की आवश्यकता होगी।
सभी प्रकार, हालांकि। उदाहरण के लिए, फिक्सनम जैसी तत्काल वस्तुओं को ठंडा करने का कोई मतलब नहीं होगा क्योंकि प्रत्येक पूर्णांक मान के अनुरूप फ़िक्सनम का प्रभावी रूप से केवल एक उदाहरण होता है। यही कारण है कि केवल String
को इस तरह से विशेष रूप से cased किया जाना चाहिए, Fixnum
और Symbol
नहीं।
स्ट्रिंग्स रूबी प्रोग्रामर के लिए सुविधा के मामले के रूप में बस एक विशेष अपवाद हैं, क्योंकि तारों को अक्सर हैश कुंजी के रूप में उपयोग किया जाता है।
इसके विपरीत, कारण यह है कि अन्य वस्तु प्रकार इस है, जो बेशक असंगत व्यवहार की ओर जाता है की तरह जमे हुए नहीं हैं, ज्यादातर Matz & कंपनी के लिए सुविधा की बात बढ़त मामलों का समर्थन नहीं है। व्यावहारिक रूप से, तुलनात्मक रूप से कुछ लोग एक कंटेनर ऑब्जेक्ट का उपयोग सरणी या हैश की हैश कुंजी के रूप में करेंगे। तो यदि आप ऐसा करते हैं, तो सम्मिलन से पहले जमा करने के लिए आप पर निर्भर है।
ध्यान दें कि यह प्रदर्शन के बारे में सख्ती से नहीं है, क्योंकि एक गैर-तत्काल वस्तु को ठंडा करने के कार्य में बिट basic.flags
बिटफील्ड पर प्रत्येक ऑब्जेक्ट पर मौजूद है। यह निश्चित रूप से एक सस्ता ऑपरेशन है।
प्रदर्शन के बारे में भी बात करते हुए, ध्यान दें कि यदि आप स्ट्रिंग कुंजियों का उपयोग करने जा रहे हैं, और आप कोड के प्रदर्शन-महत्वपूर्ण अनुभाग में हैं, तो आप सम्मिलन करने से पहले अपने तारों को फ्रीज करना चाहेंगे। यदि आप नहीं करते हैं, तो एक डुप्लिकेट ट्रिगर होता है, जो एक अधिक महंगा ऑपरेशन है।
अद्यतन @sawa ने बताया अपने सरणी कुंजी बस जमे हुए छोड़ने का मतलब है कि मूल सरणी कुंजी का उपयोग संदर्भ है, जो भी एक अप्रिय आश्चर्य हो सकता है (के अप्रत्याशित रूप से अपरिवर्तनीय बाहर हो सकता है, हालांकि OTOH यह आप सही काम करेगा एक हैश-कुंजी के रूप में एक सरणी का उपयोग करने के लिए, वास्तव में)।यदि आप इसलिए अनुमान लगाते हैं कि डुप्लिकेट उस से बाहर निकलने का तरीका है, तो आप वास्तव में संभावित ध्यान देने योग्य प्रदर्शन लागत ले सकते हैं। तीसरे हाथ पर, इसे पूरी तरह से अनजान छोड़ दें, और आपको ओपी की मूल अजीबता मिलती है। चारों ओर अजीबता। इन एज मामलों को प्रोग्रामर को स्थगित करने के लिए Matz et al के लिए एक अन्य कारण।
ऐसा लगता है, मेरे उद्देश्य के लिए, मैं सबसे अच्छा कर सकता हूं 'h.keys.each {| s | एच। स्टोर (एस। डीलकेस, एच। डिलीट (एस))} '। – sawa
मैं केवल "क्यों" पर अनुमान लगा सकता हूं। साथ ही स्ट्रिंग एरे की तुलना में अधिक सामान्य उपयोग केस होने के कारण, मुझे लगता है कि एक स्ट्रिंग को ठंडा करना लागू करना आसान होगा। अगर मुझे पर्ल पता था, तो मैं देखता हूं कि रूबी अपने हैश व्यवहार में पर्ल के साथ संगत होने की कोशिश कर रहा है या नहीं। अगर मैं जापानी में कुशल था, तो मैं देखता था कि चाबियों को ठंडा करने के दौरान लागू किया गया था, और देखें कि क्या यह एक मेलिंग सूची पर एक बग रिपोर्ट या चर्चा का परिणाम था (संभवतया रूबी के इतिहास में कुछ के लिए जापानी में)। –
@AndrewGrimm [यहां] (http://doc.ruby-lang.org/ja/1.9.2/class/Hash.html) यह कहता है कि सरणी और हैश एक हैश के लिए अच्छी चाबियाँ नहीं बनाते क्योंकि उन्हें संशोधित किया जा सकता है, और तार जमे हुए हैं ताकि आपको रिहाश कॉल न करना पड़े। Steenslag के जवाब के साथ संगत। – sawa