किसी वस्तु के परिवर्तनशील होने का क्या अर्थ है?
फैंसी शब्दों को भ्रमित न होने दें, “परिवर्तनशीलता ” का सीधा सा मतलब है कि किसी वस्तु की आंतरिक स्थिति को बदला जा सकता है। जमे हुए . को छोड़कर, यह सभी वस्तुओं का डिफ़ॉल्ट है , या वे जो विशेष वस्तुओं की सूची का हिस्सा हैं।
दूसरे शब्दों में, रूबी में सभी ऑब्जेक्ट परिवर्तनशील नहीं होते हैं!
उदाहरण के लिए :
यह संख्याओं या प्रतीकों, या यहां तक कि true
. के लिए भी कोई अर्थ नहीं रखता है या false
(जो वस्तुएं भी हैं) बदलने के लिए।
नंबर 1 हमेशा 1 रहने वाला है।
लेकिन अन्य ऑब्जेक्ट, विशेष रूप से वे जो डेटा स्टोर करने के लिए होते हैं, जैसे कि ऐरे या हैश ऑब्जेक्ट, में प्रदर्शन कारणों से बदलने की क्षमता होनी चाहिए।
विकल्प क्या है?
आप नई कॉपी बना सकते हैं परिवर्तन के साथ किसी वस्तु का और फिर मूल वस्तु को बरकरार रखते हुए इस नई वस्तु को वापस कर दें।
यदि सरणियाँ अपरिवर्तनीय होतीं और आप किसी सरणी के केवल एक तत्व को बदलना चाहते हैं, आपको सभी डेटा को कॉपी करना होगा, जिसमें वे तत्व भी शामिल हैं जो नहीं बदले हैं।
कल्पना करें कि हर बार जब आपको कोई बदलाव करना पड़े, तो एक मिलियन (या अधिक) तत्व सरणी की प्रतिलिपि बनाने की कल्पना करें, चाहे वह कितना भी छोटा क्यों न हो! बहुत कुशल नहीं…
वैसे भी।
आइए थोड़ा गहराई से देखें कि रूबी में परिवर्तनशीलता कैसे काम करती है।
संकेतक के रूप में परिवर्तनशीलता और चर
प्रोग्रामिंग त्रुटियों की एक श्रेणी है जो दो चीजों के संयोजन के कारण होती है:
- परिवर्तनीय वस्तुएं।
- तथ्य यह है कि वेरिएबल में सीधे डेटा नहीं होता है, लेकिन यह एक संदर्भ है कि यह डेटा कहाँ संग्रहीत है।
जब आप किसी वैरिएबल को 'उपनाम' करने की कोशिश करते हैं, तो ये त्रुटियां खुद को दिखाने का एक तरीका है।
यहां एक उदाहरण दिया गया है :
name = "Peter" other_name = name puts other_name # "Peter"
इस उदाहरण में, दोनों name
और other_name
एक ही स्ट्रिंग ऑब्जेक्ट का संदर्भ रखें। आप या तो इस स्ट्रिंग की सामग्री को प्रदर्शित करने या संशोधित करने के लिए उपयोग कर सकते हैं।
समस्या तब प्रकट होती है जब हम other_name
. का इलाज करते हैं स्ट्रिंग की एक प्रति की तरह।
other_name[0] = 'T' name # "Teter" other_name # "Teter"
चूंकि दोनों चर एक ही स्ट्रिंग को इंगित करते हैं, इसलिए हमने अभी "पीटर" को "टीटर" में बदल दिया है। यह एक समस्या है क्योंकि हम शायद "पीटर" को अपने पास रखना चाहते थे।
क्लोनिंग ऑब्जेक्ट्स
इस समस्या से निपटने का एक तरीका है dup
. का उपयोग करना विधि।
यह रूबी को आपको वस्तु की एक प्रति देने के लिए कहेगा। एक clone
भी है विधि, जो आपको वस्तु की एक प्रति देने के अलावा, यह जमे हुए स्थिति और वस्तु पर परिभाषित किसी भी सिंगलटन विधियों की प्रतिलिपि बनाता है।
आइए एक उदाहरण देखें :
numbers = [1, 2, 3] more_numbers = numbers.dup more_numbers << 4 numbers # [1, 2, 3] more_numbers # [1, 2, 3, 4]
इस उदाहरण में, आप देख सकते हैं कि कैसे मूल numbers
सरणी अपरिवर्तित रही। उस dup
. को हटाने का प्रयास करें तीसरी लाइन पर कॉल करें और देखें कि क्या होता है 🙂
रूबी फ्रीज विधि
किसी वस्तु को अवांछित परिवर्तनों से सुरक्षित रखने का दूसरा तरीका उसे 'फ्रीज' करना है। freeze
. का उपयोग करके किसी भी रूबी वस्तु को फ्रीज किया जा सकता है विधि।
जब कोई वस्तु जमी होती है, तो इस वस्तु को बदलने के किसी भी प्रयास के परिणामस्वरूप RuntimeError
होगा अपवाद।
नोट:आप frozen?
. का उपयोग कर सकते हैं यह जांचने की विधि कि कोई वस्तु जमी है या नहीं।
उदाहरण :
animals = %w( cat dog tiger ) animals.freeze animals << 'monkey' # RuntimeError: can't modify frozen Array
एक बात का ध्यान रखें कि यह केवल एक वस्तु को फ्रीज करेगा, इस उदाहरण में सरणी ही, जो हमें इसमें से आइटम जोड़ने या निकालने से रोकती है। लेकिन सरणी के अंदर के तार जमे नहीं हैं, इसलिए उन्हें अभी भी बदला जा सकता है !
animals[1][0] = 't' # => ["cat", "tog", "tiger"]
यदि आप स्ट्रिंग्स को फ़्रीज़ करना चाहते हैं तो आपको freeze
. पर कॉल करने की आवश्यकता है उन पर। इस तरह:animals.each(&:freeze)
।
जमे हुए तार
परिवर्तनशील वस्तुओं का प्रदर्शन पर भी प्रभाव पड़ता है, विशेष रूप से तार। इसका कारण यह है कि इस बात की अच्छी संभावना है कि एक बड़े प्रोग्राम में एक ही स्ट्रिंग को कई बार इस्तेमाल किया जाता है।
रूबी प्रत्येक स्ट्रिंग के लिए एक नई वस्तु बनाएगी, भले ही दो तार समान दिखें, या दूसरे शब्दों में, उनके पास समान 'सामग्री' हो। आप इसे irb
. में आसानी से देख सकते हैं यदि आप object_id
का उपयोग करते हैं विधि।
यहां एक उदाहरण दिया गया है :
a = 'test' b = 'test' a.object_id # 76325640 b.object_id # 76317550
यह एक समस्या है क्योंकि ये ऑब्जेक्ट अतिरिक्त मेमोरी और अतिरिक्त CPU चक्र का उपभोग कर रहे हैं।
रूबी 2.1 से शुरू करते हुए, जब आप जमे हुए तार का उपयोग करते हैं , रूबी उसी स्ट्रिंग ऑब्जेक्ट का उपयोग करेगी। यह उसी स्ट्रिंग की नई प्रतियां बनाने से बचा जाता है। जिसके परिणामस्वरूप कुछ मेमोरी बचत होती है और एक छोटा प्रदर्शन बूस्ट होता है।
रेल व्यापक . बनाता है इस कारण से जमे हुए तारों का उपयोग। उदाहरण के लिए, इस जनसंपर्क पर एक नज़र डालें।
इसने रूबी डेवलपमेंट टीम को स्ट्रिंग्स को अपरिवर्तनीय . में स्थानांतरित करने पर विचार करने के लिए प्रेरित किया डिफ़ॉल्ट रूप से ऑब्जेक्ट। वास्तव में, रूबी 2.3, जिसे अभी कुछ दिन पहले जारी किया गया था, इसमें आपके प्रोजेक्ट के लिए इसे सक्षम करने के दो तरीके शामिल हैं।
एक को शामिल करना है # frozen_string_literal: true
प्रत्येक फ़ाइल के शीर्ष पर जहाँ आप चाहते हैं कि तार अपरिवर्तनीय हों। और दूसरा कमांड-लाइन तर्क का उपयोग करना है --enable=frozen-string-literal
।
डिफ़ॉल्ट रूप से अपरिवर्तनीय तार शायद रूबी 3.0 में उतरेंगे।
अब पागल न हों और अपने ऐप में अपने सभी स्ट्रिंग्स को फ्रीज़ करना शुरू करें। आप इसे केवल उन स्ट्रिंग्स के लिए करना चाहते हैं जिनका उपयोग किसी प्रकार के लाभ देखने के लिए सैकड़ों बार किया जाता है . इतना कहने के बाद, यहाँ एक उपकरण है जिसका उपयोग आप संभावित स्ट्रिंग्स को फ़्रीज़ करने के लिए ढूँढ़ने के लिए कर सकते हैं।
अपने तरीके जानें
एक परिवर्तनशील वस्तु में सभी विधियाँ वास्तव में वस्तु को नहीं बदलेंगी, उदाहरण के लिए, gsub विधि मूल को अछूता छोड़कर एक नई स्ट्रिंग लौटाएगी।
इनमें से कुछ विधियों का वैकल्पिक संस्करण . है जो मूल वस्तु को जगह में बदल देता है, जो अक्सर अधिक कुशल होता है। ये विधियां अक्सर विस्मयादिबोधक चिह्न !
. के साथ समाप्त होती हैं उनके प्रभाव को इंगित करने के लिए।
इन 'बैंग' विधियों के दो उदाहरण हैं gsub!
और map!
।
इस पर ध्यान दें :
!
. में समाप्त होने वाली एक विधि इसका हमेशा यह मतलब नहीं होता है कि यह एक ऐसी 'विधि है जो किसी वस्तु को बदल देती है'।
अधिक सामान्य शब्दों में, !
प्रतीक का प्रयोग 'खतरे' को दर्शाने के लिए किया जाता है। एक उदाहरण इसमें से exit!
विधि, जो किसी भी निकास हैंडलर को अनदेखा करते हुए तुरंत प्रोग्राम से बाहर निकल जाएगी।
ऐसे तरीके भी हैं जो ऑब्जेक्ट को बदलते हैं और !
. के साथ समाप्त नहीं होते हैं चिन्ह, प्रतीक। उदाहरण के लिए:delete
, clear
, push
, concat
, और भी बहुत कुछ।
रैपिंग अप
परिवर्तनशीलता एक मुश्किल विषय हो सकता है, लेकिन जब से आपने इस पोस्ट को पढ़ा है, अब आप इससे निपटने के लिए बेहतर तरीके से तैयार हैं। यदि आप सुनिश्चित नहीं हैं कि कोई विधि क्या कर रही है, तो रूबी दस्तावेज़ देखें, इससे आपको समस्याओं से बचने में मदद मिलेगी।
मुझे आशा है कि आपको यह लेख जानकारीपूर्ण लगा होगा, कृपया साझा करें इसे अपने मित्रों के साथ रखें ताकि वे आनंद कर सकें यह भी। नीचे मेरे न्यूज़लेटर में भी शामिल हों ताकि जब यह सामने आए तो आप इस तरह की और सामग्री को याद न करें!