arrays क्यों हैश में किसी सरणी के लिए एक मूल्य जोड़ना अन्य चर को संशोधित करेगा जो इसे सौंपा है?




ruby hash (4)

नमूना कोड:

hash_of_array = { a: [] }
b = hash_of_array
c = hash_of_array

b[:a] << 1

puts b # => { a: [1] }
puts c # => { a: [1] }

दोनों चर क्यों उनके सरणी में 1 है? मैं केवल इसे चर b पर जोड़ा था।

कोशिश की

  • रुबी संस्करण 2.3.1, 2.4.0
  • Rbenv

मैं जॉन नामक व्यक्ति को जानता हूं कुछ उसे जॉनी कहते हैं जॉनी आज गोली मार दी। जॉन को भी गोली क्यों मिली?

foo = _something_

बस _something_ लिए वैकल्पिक नाम foo देता है यह इसे क्लोन नहीं करता है या कोई अन्य शैनैनिगन्स नहीं करता है


जैसा कि पहले उल्लेख किया गया है, उत्कृष्ट उत्तर, आपके सामने की समस्या यह है कि ए और बी समान ऑब्जेक्ट हैं एक अन्य जवाब (बाद में नष्ट कर दिया गया) दप पद्धति का उपयोग करने की सिफारिश की गई, अगर कोई उथले प्रति पर्याप्त था। समस्या यह है कि आपके परिदृश्य में, एक उथले प्रतिलिपि पर्याप्त नहीं है

मैं full_dup रत्न की कोशिश करने का प्रस्ताव देता हूं यह मणि एक नई विधि जोड़ता है, जिसे फ़ुल_ड्यूप कहा जाता है। एक full_dup आपकी वस्तुओं की एक गहरी प्रतिलिपि बनाता है तो आपका उदाहरण दिया गया है:

require 'full_dup'

hash_of_array = { a: [] }
b = hash_of_array.full_dup
c = hash_of_array.full_dup

b[:a] << 1

puts b # => { a: [1] }
puts c # => { a: [] }

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

उफ़; ज़िक्र करना भूल गया। मैं full_dup रत्न के लेखक हूँ


रब्बी के सभी ऑब्जेक्ट को सही, गलत, शून्य और फिक्सनम के अपवाद के साथ संदर्भ द्वारा असाइन किया जाता है जो विशेष रूप से नियंत्रित होते हैं।

आप object_id को देखकर इसका परीक्षण कर सकते हैं

irb(main):001:0> a = [1,2,3]
=> [1, 2, 3]
irb(main):002:0> b = a
=> [1, 2, 3]
irb(main):003:0> a.object_id == b.object_id
=> true

किसी वस्तु की एक प्रति बनाने के लिए, .dup उपयोग .dup

irb(main):005:0> b = a.dup
=> [1, 2, 3]
irb(main):006:0> a.object_id == b.object_id
=> false

आपके उदाहरण के लिए, आपको एक गहरी कॉपी की आवश्यकता है, ताकि आप कर सकें

Marshal.load(Marshal.dump(hash))

इसलिए,

irb(main):037:0> a = {a: []}
=> {:a=>[]}
irb(main):038:0> b = Marshal.load(Marshal.dump(a))
=> {:a=>[]}
irb(main):039:0> b[:a] << 1
=> [1]
irb(main):040:0> b
=> {:a=>[1]}
irb(main):041:0> a
=> {:a=>[]}

आपके उदाहरण में, और @AndreyDeineko , b और c द्वारा उल्लिखित मूल रूप से एक ही वस्तु है।

उस व्यवहार को प्रदर्शित करने की आवश्यकता नहीं है, जिसे आप भ्रमित कर रहे हैं, हालांकि।

क्या महत्वपूर्ण है कि वे एक ही सरणी का संदर्भ रखते हैं:

array = []

b = { b: array }
c = { c: array }

puts b == c
#=> false

puts b.object_id == c.object_id
#=> false

puts b[:b].object_id == c[:c].object_id
#=> true

b[:b] << 'test'

p b
# {:b=>["test"]}
p c
# {:c=>["test"]}




hash