2012-02-18 15 views
45

मैं Ruby Koans tutorial series के माध्यम से जा रहा था, जब मैं about_hashes.rb में इस पर आया था:शोवेल (<<) ऑपरेटर रूबी हैश में कैसे काम करता है?

def test_default_value_is_the_same_object 
    hash = Hash.new([]) 

    hash[:one] << "uno" 
    hash[:two] << "dos" 

    assert_equal ["uno", "dos"], hash[:one] 
    assert_equal ["uno", "dos"], hash[:two] 
    assert_equal ["uno", "dos"], hash[:three] 

    assert_equal true, hash[:one].object_id == hash[:two].object_id 
end 

मूल्यों assert_equals में, क्या ट्यूटोरियल की उम्मीद वास्तव में है। लेकिन मुझे समझ में नहीं आया कि << ऑपरेटर और = ऑपरेटर का उपयोग करने के बीच क्या अंतर है?

मेरे उम्मीद थी कि:

  • hash[:one] होगा ["uno"]
  • hash[:two] होगा ["dos"]
  • hash[:three] होगा []

किसी कृपया समझा सकता है क्यों मेरे उम्मीद गलत था?

+4

मजेदार, यह वही है जो मैंने अपेक्षित था। फिर, पहाड़ फिर से पहाड़ थे। –

उत्तर

52

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

h = Hash.new([]) 
h[:foo].object_id # => 12215540 
h[:bar].object_id # => 12215540 

आपको प्रति कुंजी एक सरणी चाहते हैं, आप Hash.new के ब्लॉक सिंटैक्स का उपयोग करने के लिए है:

h = Hash.new { |h, k| h[k] = [] } 
h[:foo].object_id # => 7791280 
h[:bar].object_id # => 7790760 

संपादित करें: भी देखें Gazler क्या #<< विधि के संबंध में क्या कहना है और आप किस वस्तु पर वास्तव में इसे बुला रहे हैं।

+1

+1। – Gazler

+0

इसे धन्यवाद मिला। इसलिए, मूल खाली सरणी एक ऑब्जेक्ट है जिसे डिफ़ॉल्ट मान के रूप में संग्रहीत किया जाता है। और हम उस मूल वस्तु को 'शून्य' के बजाय वापस लेते रहते हैं। साफ! दोनों उत्तरों (आपके द्वारा और @ गज़लर) दोनों के लिए धन्यवाद, दोनों को ऊपर उठाना, लेकिन इसे स्वीकार करना। – bits

58

आपने इस तरह से काम किया है जिस तरह से यह मिला है। सबसे पहले, हैश में << विधि नहीं है, तो आपके उदाहरण में यह विधि सरणी पर मौजूद है।

आपका कोड त्रुटि नहीं दे रहा है क्योंकि आप कन्स्ट्रक्टर के माध्यम से अपने हैश के लिए डिफ़ॉल्ट मान पास कर रहे हैं। http://ruby-doc.org/core-1.9.3/Hash.html#method-c-new

hash = Hash.new([]) 

इसका मतलब यह है कि अगर एक कुंजी मौजूद नहीं है, तो यह एक सरणी वापस आ जाएगी। यदि आप निम्न कोड चलाते हैं:

hash = {} 
hash[:one] << "uno" 

फिर आपको एक अपरिभाषित विधि त्रुटि प्राप्त होगी।

अपने उदाहरण में

तो, क्या वास्तव में हो रहा है:

hash = Hash.new([]) 

hash[:one] << "uno" #hash[:one] does not exist so return an array and push "uno" 
hash[:two] << "dos" #hash[:two] does not exist, so return the array ["uno"] and push "dos" 

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

+2

धन्यवाद @ गैज़लर। इससे इसे स्पष्ट करने में मदद मिली। – bits

+1

आपको बहुत धन्यवाद – Etch

+4

यह स्वीकार्य उत्तर होना चाहिए। अधिक स्पष्ट स्पष्टीकरण।धन्यवाद –

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