ruby - रूबी के attr_accessor, attr_reader और attr_writer का उपयोग क्यों करें?




(4)

रूबी जैसे कुंजी का उपयोग करके इंस्टेंस चर साझा करने के लिए यह आसान और सुविधाजनक तरीका है

attr_accessor :var
attr_reader :var
attr_writer :var

अगर मैं attr_accessor उपयोग कर सकता हूं तो मैं attr_reader या attr_writer क्यों attr_accessor ? क्या प्रदर्शन की तरह कुछ है (जो मुझे शक है)? मुझे लगता है कि एक कारण है, अन्यथा वे ऐसी चाबियाँ नहीं बनाते थे।


आप अपने कोड को पढ़ने वाले किसी व्यक्ति को अपने इरादे से संवाद करने के लिए अलग-अलग एक्सेसर्स का उपयोग कर सकते हैं, और कक्षाओं को लिखना आसान बना सकते हैं जो सही तरीके से काम करेंगे चाहे कोई भी सार्वजनिक एपीआई कैसे कहा जाता है।

class Person
  attr_accessor :age
  ...
end

यहां, मैं देख सकता हूं कि मैं दोनों उम्र पढ़ और लिख सकता हूं।

class Person
  attr_reader :age
  ...
end

यहां, मैं देख सकता हूं कि मैं केवल उम्र पढ़ सकता हूं। कल्पना कीजिए कि यह इस वर्ग के निर्माता द्वारा निर्धारित है और उसके बाद स्थिर रहता है। यदि उम्र के लिए एक उत्परिवर्ती (लेखक) था और कक्षा को यह माना जाता था कि उम्र, एक बार सेट हो जाती है, तो बदलती नहीं है, तो एक बग कोडक कॉलिंग से परिणामस्वरूप हो सकता है।

लेकिन दृश्यों के पीछे क्या हो रहा है?

यदि आप लिखते हैं:

attr_writer :age

इसका अनुवाद हो जाता है:

def age=(value)
  @age = value
end

यदि आप लिखते हैं:

attr_reader :age

इसका अनुवाद हो जाता है:

def age
  @age
end

यदि आप लिखते हैं:

attr_accessor :age

इसका अनुवाद हो जाता है:

def age=(value)
  @age = value
end

def age
  @age
end

यह जानकर, इसके बारे में सोचने का एक और तरीका यहां है: यदि आपके पास attr _... सहायक नहीं थे, और आपको एक्सेसर्स लिखना पड़ा, तो क्या आप अपनी कक्षा की तुलना में और अधिक एक्सेसर्स लिखेंगे? उदाहरण के लिए, यदि उम्र केवल पढ़ने की आवश्यकता है, तो क्या आप इसे लिखने की अनुमति देने के लिए एक विधि भी लिखेंगे?


आप हमेशा कक्षा के बाहर से अपने आवृत्ति चर पूरी तरह से सुलभ नहीं होना चाहते हैं। ऐसे कई मामले हैं जहां एक आवृत्ति परिवर्तनीय को पढ़ने की इजाजत मिलती है, लेकिन इसे लिखना संभव नहीं है (उदाहरण के लिए एक मॉडल जो केवल पढ़ने के स्रोत से डेटा पुनर्प्राप्त करता है)। ऐसे मामले हैं जहां आप विपरीत चाहते हैं, लेकिन मैं किसी ऐसे व्यक्ति के बारे में नहीं सोच सकता जो मेरे सिर के ऊपर से नहीं है।


किसी ऑब्जेक्ट के सभी गुण सीधे वर्ग के बाहर से सेट करने के लिए नहीं हैं। आपके सभी इंस्टेंस वैरिएबल के लिए लेखकों को आम तौर पर कमजोर encapsulation का संकेत है और एक चेतावनी है कि आप अपने वर्गों के बीच बहुत अधिक युग्मन शुरू कर रहे हैं।

व्यावहारिक उदाहरण के रूप में: मैंने एक डिज़ाइन प्रोग्राम लिखा जहां आपने कंटेनरों के अंदर आइटम डाले। आइटम में attr_reader :container था attr_reader :container , लेकिन लेखक को पेश करने का कोई मतलब नहीं था, क्योंकि आइटम के कंटेनर को बदलने के लिए केवल एक ही समय में इसे एक नए स्थान पर रखा जाना चाहिए, जिसके लिए स्थिति की जानकारी भी आवश्यक है।


यह समझना महत्वपूर्ण है कि एक्सेसर्स चर के उपयोग को प्रतिबंधित करते हैं, लेकिन उनकी सामग्री नहीं। रूबी में, कुछ अन्य ओओ भाषाओं की तरह, प्रत्येक चर एक उदाहरण के लिए एक सूचक है। इसलिए यदि आपके पास हैश में एक विशेषता है, उदाहरण के लिए, और आप इसे "केवल पढ़ने" के लिए सेट करते हैं, तो आप हमेशा इसकी सामग्री बदल सकते हैं, लेकिन सूचक की सामग्री नहीं। इसे देखो:

irb(main):024:0> class A
irb(main):025:1> attr_reader :a
irb(main):026:1> def initialize
irb(main):027:2> @a = {a:1, b:2}
irb(main):028:2> end
irb(main):029:1> end
=> :initialize
irb(main):030:0> a = A.new
=> #<A:0x007ffc5a10fe88 @a={:a=>1, :b=>2}>
irb(main):031:0> a.a
=> {:a=>1, :b=>2}
irb(main):032:0> a.a.delete(:b)
=> 2
irb(main):033:0> a.a
=> {:a=>1}
irb(main):034:0> a.a = {}
NoMethodError: undefined method `a=' for #<A:0x007ffc5a10fe88 @a={:a=>1}>
        from (irb):34
        from /usr/local/bin/irb:11:in `<main>'

जैसा कि आप देख सकते हैं संभव है हैश @ ए से एक कुंजी / मान जोड़ी हटाएं, जैसे कि नई कुंजी जोड़ें, मान बदलें, एक्सेटेरा। लेकिन आप एक नई ऑब्जेक्ट को इंगित नहीं कर सकते क्योंकि केवल पढ़ने के लिए आवृत्ति चर है।





ruby