मुझे रूबी को समझने attr_accessor
में कठिन समय आ रहा है ।
क्या कोई मुझे ये समझा सकता है?
मुझे रूबी को समझने attr_accessor
में कठिन समय आ रहा है ।
क्या कोई मुझे ये समझा सकता है?
जवाबों:
मान लीजिए कि आपके पास एक वर्ग है Person
।
class Person
end
person = Person.new
person.name # => no method error
जाहिर है हमने कभी भी पद्धति को परिभाषित नहीं किया है name
। चलो करते हैं।
class Person
def name
@name # simply returning an instance variable @name
end
end
person = Person.new
person.name # => nil
person.name = "Dennis" # => no method error
अहा, हम नाम पढ़ सकते हैं, लेकिन इसका मतलब यह नहीं है कि हम नाम निर्दिष्ट कर सकते हैं। वे दो अलग-अलग विधियाँ हैं। पूर्व को पाठक कहा जाता है और बाद को लेखक कहा जाता है । हमने लेखक अभी तक नहीं बनाया है तो चलो ऐसा करते हैं।
class Person
def name
@name
end
def name=(str)
@name = str
end
end
person = Person.new
person.name = 'Dennis'
person.name # => "Dennis"
बहुत बढ़िया। अब हम @name
पाठक और लेखक विधियों का उपयोग करके उदाहरण चर लिख और पढ़ सकते हैं । को छोड़कर, ऐसा अक्सर किया जाता है, क्यों हर बार इन तरीकों को लिखने में समय बर्बाद किया जाता है? हम इसे आसान कर सकते हैं।
class Person
attr_reader :name
attr_writer :name
end
यहां तक कि इससे पुनरावृत्ति भी हो सकती है। जब आप पाठक और लेखक दोनों चाहते हैं तो बस एक्सेसर का उपयोग करें!
class Person
attr_accessor :name
end
person = Person.new
person.name = "Dennis"
person.name # => "Dennis"
उसी तरह काम करता है! और लगता है क्या: @name
हमारे व्यक्ति वस्तु में उदाहरण चर की तरह ही सेट किया जाएगा जब हमने इसे मैन्युअल रूप से किया था, इसलिए आप इसे अन्य तरीकों से उपयोग कर सकते हैं।
class Person
attr_accessor :name
def greeting
"Hello #{@name}"
end
end
person = Person.new
person.name = "Dennis"
person.greeting # => "Hello Dennis"
बस। यह समझने के लिए कि कैसे attr_reader
, attr_writer
और attr_accessor
विधियाँ वास्तव में आपके लिए विधियाँ उत्पन्न करती हैं, अन्य उत्तर, किताबें, रूबी डॉक्स पढ़ें।
attr_accessor
वर्तमान कक्षा में कहा जाने वाला एक तरीका है, और :name
एक पैरामीटर है जिसे आप उस विधि से पास करते हैं। यह एक विशेष वाक्यविन्यास नहीं है, यह एक सरल विधि है। यदि आप इसे @name
परिवर्तनशील देना चाहते हैं, तो इसका कोई मतलब नहीं होगा, क्योंकि @name में शामिल होगा nil
। तो यह लिखने जैसा होगा attr_accessor nil
। आप इसे एक चर नहीं दे रहे हैं जिसे इसे बनाने की आवश्यकता है, आप उस नाम को पारित कर रहे हैं जिसे आप चाहते हैं कि चर कहा जाए।
name
और चर @name
एक ही चीज नहीं हैं। उन्हें भ्रमित मत करो। आपके पास @name
अपनी कक्षा में उदाहरण चर है, और आप attr_reader :name
इसे बाहर से पढ़ने में सक्षम होने के लिए परिभाषित करते हैं। इसके बिना attr_reader
कोई सरल तरीका नहीं है जिससे आप @name
अपनी कक्षा के बाहर पहुँच सकते हैं ।
attr_accessor है सिर्फ एक विधि । (लिंक यह कैसे काम करता है के साथ अधिक अंतर्दृष्टि प्रदान करना चाहिए - उत्पन्न विधियों के जोड़े को देखो, और एक ट्यूटोरियल आपको यह दिखाना चाहिए कि इसका उपयोग कैसे करना है।)
चाल यह है कि class
है एक परिभाषा नहीं रूबी में (यह "सिर्फ एक परिभाषा" सी ++ और जावा जैसी भाषाओं में), लेकिन यह एक है कि मूल्यांकन करता है अभिव्यक्ति । यह इस मूल्यांकन के दौरान है जब attr_accessor
विधि को लागू किया जाता है जो बदले में वर्तमान वर्ग को संशोधित करता है - निहित रिसीवर को याद रखें: self.attr_accessor
जहां self
इस बिंदु पर "खुला" वर्ग ऑब्जेक्ट है।
attr_accessor
और दोस्तों की आवश्यकता है:
रूबी, स्मॉलटाक की तरह, उदाहरण के चर को उस वस्तु के लिए विधियों 1 के बाहर तक पहुँचने की अनुमति नहीं देता है । उदाहरण के लिए, उदाहरण के चर को उस x.y
रूप में एक्सेस नहीं किया जा सकता जैसा कि जावा, या पायथन में भी सामान्य है। रूबी y
में हमेशा एक संदेश भेजने के लिए (या "कॉल करने की विधि") के रूप में लिया जाता है। इस प्रकार attr_*
विधियाँ ऐसे रैपर बनाती हैं जो @variable
डायनेमिक रूप से निर्मित विधियों के माध्यम से आवृत्ति तक पहुँच प्राप्त करते हैं।
बॉयलरप्लेट बेकार है
आशा है कि यह कुछ छोटे विवरणों को स्पष्ट करता है। खुश कोडिंग।
1 यह कड़ाई से सच नहीं है और इसके आस-पास कुछ "तकनीकें" हैं , लेकिन "सार्वजनिक उदाहरण चर" एक्सेस के लिए कोई सिंटैक्स समर्थन नहीं है।
attr_accessor
एक विधि के रूप में (@pst कहा गया है) है। यह क्या करता है आप के लिए और अधिक तरीकों का निर्माण।
तो यह कोड यहाँ है:
class Foo
attr_accessor :bar
end
इस कोड के बराबर है:
class Foo
def bar
@bar
end
def bar=( new_value )
@bar = new_value
end
end
आप रूबी में स्वयं इस प्रकार की विधि लिख सकते हैं:
class Module
def var( method_name )
inst_variable_name = "@#{method_name}".to_sym
define_method method_name do
instance_variable_get inst_variable_name
end
define_method "#{method_name}=" do |new_value|
instance_variable_set inst_variable_name, new_value
end
end
end
class Foo
var :bar
end
f = Foo.new
p f.bar #=> nil
f.bar = 42
p f.bar #=> 42
attr_accessor
और अंत में यहां पाया गया! हालांकि इससे मेरी समस्या हल हो गई, लेकिन मैं यह जानने के लिए उत्सुक हूं कि (पुस्तक / आधिकारिक डॉक्टर) मैं इस तरह का कार्यान्वयन उदाहरण कहां पा सकता हूं?
attr_accessor
बहुत सरल है:
attr_accessor :foo
इसके लिए एक शॉर्टकट है:
def foo=(val)
@foo = val
end
def foo
@foo
end
यह किसी वस्तु के लिए एक गेटटर / सेटर से ज्यादा कुछ नहीं है
मूल रूप से वे सार्वजनिक रूप से सुलभ डेटा विशेषताओं को नकली करते हैं, जो रूबी के पास नहीं है।
यह सिर्फ एक विधि है जो उदाहरण चर के लिए गेट्टर और सेटर विधियों को परिभाषित करता है। एक उदाहरण कार्यान्वयन होगा:
def self.attr_accessor(*names)
names.each do |name|
define_method(name) {instance_variable_get("@#{name}")} # This is the getter
define_method("#{name}=") {|arg| instance_variable_set("@#{name}", arg)} # This is the setter
end
end
अधिकांश उपरोक्त उत्तर कोड का उपयोग करते हैं। यह स्पष्टीकरण किसी सादृश्य / कहानी के माध्यम से बिना किसी का उपयोग किए इसका उत्तर देने का प्रयास करता है:
बाहरी पक्ष आंतरिक CIA रहस्यों का उपयोग नहीं कर सकते
आइए एक बहुत ही गुप्त स्थान की कल्पना करें: CIA। किसी को नहीं पता कि सीआईए के अंदर के लोगों के अलावा सीआईए में क्या हो रहा है। दूसरे शब्दों में, बाहरी लोग सीआईए में किसी भी जानकारी का उपयोग नहीं कर सकते हैं। लेकिन क्योंकि यह कोई अच्छा संगठन नहीं है जो पूरी तरह से गुप्त है, कुछ जानकारी बाहर की दुनिया को उपलब्ध कराई जाती है - केवल ऐसी चीजें जो CIA चाहती है कि हर कोई निश्चित रूप से इसके बारे में जानें: उदाहरण के लिए CIA के निदेशक, इस विभाग की तुलना में पर्यावरण के अनुकूल कैसे हैं अन्य सभी सरकारी विभागों आदि के लिए। अन्य जानकारी: जैसे कि इराक या अफगानिस्तान में इसके गुप्त संचालक कौन हैं - इस प्रकार की चीजें संभवतः अगले 150 वर्षों तक एक रहस्य बनी रहेंगी।
यदि आप सीआईए के बाहर हैं तो आप केवल उस जानकारी तक पहुंच सकते हैं, जिसे उसने जनता के लिए उपलब्ध कराया है। या सीआईए पार्लेंस का उपयोग करने के लिए आप केवल "क्लीयर" की गई जानकारी तक पहुंच सकते हैं।
सीआईए के बाहर आम जनता के लिए सीआईए जो जानकारी उपलब्ध कराना चाहता है, उसे कहा जाता है: विशेषताएँ।
विशेषताओं को पढ़ने और लिखने का अर्थ:
CIA के मामले में, अधिकांश विशेषताएँ "केवल पढ़ने के लिए" हैं। इसका मतलब है कि यदि आप सीआईए के लिए बाहरी पार्टी हैं , तो आप पूछ सकते हैं: "सीआईए का निदेशक कौन है?" और आपको सीधा जवाब मिलेगा। लेकिन आप "केवल पढ़ने के लिए" विशेषताओं के साथ क्या नहीं कर सकते हैं , सीआईए में परिवर्तन करना है। उदाहरण के लिए आप फोन कॉल नहीं कर सकते हैं और अचानक तय करते हैं कि आप चाहते हैं कि किम कार्दशियन निर्देशक हों, या आप चाहते हैं कि पेरिस हिल्टन इन चीफ कमांडर बनें।
यदि विशेषताओं ने आपको "लिखना" पहुंच दी है, तो आप चाहें तो बदलाव कर सकते हैं, भले ही आप बाहर थे। अन्यथा, केवल एक चीज जो आप कर सकते हैं वह है।
दूसरे शब्दों में, एक्सेसर्स आपको पूछताछ करने, या उन संगठनों में बदलाव करने की अनुमति देते हैं जो अन्यथा बाहरी लोगों को अंदर नहीं जाने देते हैं, इस पर निर्भर करता है कि एक्सेसर्स पढ़े गए हैं या एक्सेसर्स लिखते हैं।
एक वर्ग के अंदर की वस्तुएँ आसानी से एक दूसरे तक पहुँच सकती हैं
कक्षाओं और अपने भीतर चर, संपत्तियों और तरीकों तक पहुंचने की क्षमता के साथ एक ही चीज का सटीक निष्पादन करें। HTH! कोई प्रश्न, कृपया पूछें और मुझे आशा है कि मैं स्पष्ट कर सकता हूं।
यदि आप OOP अवधारणा से परिचित हैं, तो आपको गेट्टर और सेटर विधि से परिचित होना चाहिए। attr_accessor रूबी में यही करता है।
सामान्य तरीके से गेटटर और सेटर
class Person
def name
@name
end
def name=(str)
@name = str
end
end
person = Person.new
person.name = 'Eshaan'
person.name # => "Eshaan"
सेटर विधि
def name=(val)
@name = val
end
गेट्टर विधि
def name
@name
end
रूबी में गेट्टर और सेटर विधि
class Person
attr_accessor :name
end
person = Person.new
person.name = "Eshaan"
person.name # => "Eshaan"
मैंने इस समस्या का सामना किया और इस सवाल का कुछ लंबा जवाब लिखा। इस पर पहले से ही कुछ शानदार जवाब हैं, लेकिन किसी को भी अधिक स्पष्टीकरण की तलाश है, मुझे उम्मीद है कि मेरा जवाब मदद कर सकता है
प्रारंभिक विधि
प्रारंभ में आपको प्रत्येक बार जब आप कक्षा का एक नया उदाहरण बनाते हैं तो कोड में एक अलग लाइन पर उन्हें सेट करने के बजाय उदाहरण के निर्माण पर किसी ऑब्जेक्ट के इंस्टेंस पर डेटा सेट करने की अनुमति देता है।
class Person
def initialize(name)
@name = name
end
def greeting
"Hello #{@name}"
end
end
person = Person.new("Denis")
puts person.greeting
ऊपर दिए गए कोड में हम डेनिस को इनिशियलाइज़ में पैरामीटर के माध्यम से पास करके प्रारंभिक विधि का उपयोग करके "डेनिस" नाम सेट कर रहे हैं। अगर हम बिना नाम के तरीका तय करना चाहते थे तो हम ऐसा कर सकते थे:
class Person
attr_accessor :name
# def initialize(name)
# @name = name
# end
def greeting
"Hello #{name}"
end
end
person = Person.new
person.name = "Dennis"
puts person.greeting
उपरोक्त कोड में, हम ऑब्जेक्ट के आरंभीकरण पर मूल्यों को सेट करने के बजाय person.name का उपयोग करके attr_accessor सेटर विधि पर कॉल करके नाम सेट करते हैं।
इस काम को करने के दोनों "तरीके", लेकिन इनिशियलाइज़ हमें समय और कोड की लाइनों को बचाता है।
यह इनिशियलाइज़ का एकमात्र काम है। आप एक विधि के रूप में इनिशियलाइज़ नहीं कर सकते। वास्तव में एक उदाहरण ऑब्जेक्ट के मूल्यों को प्राप्त करने के लिए आपको गेटर्स और सेटर (attr_reader (get), attr_writer (सेट), और attr_accessor (दोनों)) का उपयोग करने की आवश्यकता होती है। उन पर अधिक विस्तार के लिए नीचे देखें।
गेटर्स, सेटर्स (attr_reader, attr_writer, attr_accessor)
गेटर्स, एट्र्रैडर: एक गेटर का पूरा उद्देश्य किसी विशेष उदाहरण चर के मान को वापस करना है। इस पर ब्रेकडाउन के लिए नीचे दिए गए सैंपल कोड पर जाएँ।
class Item
def initialize(item_name, quantity)
@item_name = item_name
@quantity = quantity
end
def item_name
@item_name
end
def quantity
@quantity
end
end
example = Item.new("TV",2)
puts example.item_name
puts example.quantity
ऊपर दिए गए कोड में आप आइटम "उदाहरण" के उदाहरण पर "आइटम_नाम" और "मात्रा" कह रहे हैं। "Example.item_name" और "example.quantity" वापस आ जाएगी (या "प्राप्त करें") उन मापदंडों के लिए मान जो "उदाहरण" में पारित किए गए थे और उन्हें स्क्रीन पर प्रदर्शित करते हैं।
सौभाग्य से रूबी में एक अंतर्निहित विधि है जो हमें इस कोड को अधिक संक्षेप में लिखने की अनुमति देती है; Attr_reader विधि। नीचे दिए गए कोड को देखें;
class Item
attr_reader :item_name, :quantity
def initialize(item_name, quantity)
@item_name = item_name
@quantity = quantity
end
end
item = Item.new("TV",2)
puts item.item_name
puts item.quantity
यह सिंटैक्स ठीक उसी तरह से काम करता है, केवल यह हमें कोड की छह लाइनें बचाता है। कल्पना कीजिए कि क्या आपके पास आइटम वर्ग के लिए 5 और राज्य थे? कोड बहुत जल्दी मिल जाएगा।
सेटर्स, एट्री_राइटर: सेटर विधियों के साथ पहली बार में जो मुझे पार कर गया, वह यह है कि मेरी नजर में यह इनिशियलाइज़ मेथड को एक समान कार्य करता प्रतीत हो रहा था। नीचे मैं अपनी समझ के आधार पर अंतर समझाता हूं;
जैसा कि पहले कहा गया है, इनिशियलाइज़ विधि आपको ऑब्जेक्ट निर्माण पर ऑब्जेक्ट की आवृत्ति के लिए मान सेट करने की अनुमति देता है।
लेकिन क्या होगा अगर आप उदाहरणों को बाद में स्थापित करना चाहते थे, उदाहरण के लिए, या उन्हें शुरू करने के बाद उन्हें बदल दें? यह एक ऐसा परिदृश्य होगा जहां आप एक सेटर विधि का उपयोग करेंगे। यह ज्ञान है। जब आप प्रारंभ में attr_writer पद्धति का उपयोग कर रहे हों, तो आपको किसी विशेष स्थिति को "सेट" करने की आवश्यकता नहीं है।
नीचे दिया गया कोड आइटम वर्ग के इस उदाहरण के लिए value_name को घोषित करने के लिए एक सेटर विधि का उपयोग करने का एक उदाहरण है। ध्यान दें कि हम गेट्टर विधि का उपयोग करना जारी रखते हैं ताकि हम मान प्राप्त कर सकें और उन्हें स्क्रीन पर प्रिंट कर सकें, बस अगर आप अपने दम पर कोड का परीक्षण करना चाहते हैं।
class Item
attr_reader :item_name
def item_name=(str)
@item_name = (str)
end
end
नीचे दिया गया कोड एक बार फिर से हमारे कोड को छोटा करने और हमें समय बचाने के लिए attr_writer का उपयोग करने का एक उदाहरण है।
class Item
attr_reader :item_name
attr_writer :item_name
end
item = Item.new
puts item.item_name = "TV"
नीचे दिया गया कोड ऊपर के इनिशियलाइज़ उदाहरण का एक पुनरीक्षण है, जहाँ हम इनिशियलाइज़ का उपयोग कर रहे हैं सृजन पर item_name की ऑब्जेक्ट वैल्यू सेट करने के लिए।
class Item
attr_reader :item_name
def initialize(item_name)
@item_name = item_name
end
end
item = Item.new("TV")
puts item.item_name
attr_accessor: attr_reader और attr_writer दोनों के कार्यों को करता है, जिससे आपको कोड की एक और लाइन की बचत होती है।
मुझे लगता है कि नए रूबिस्ट / प्रोग्रामर (जैसे खुद) क्या भ्रमित हैं:
"मैं सिर्फ यह उदाहरण क्यों नहीं बता सकता कि इसमें कोई विशेषता है (उदाहरण के लिए, नाम) और उस विशेषता को एक झपट्टा में सभी मान दें?"
थोड़ा और सामान्यीकृत, लेकिन यह इस तरह से मेरे लिए क्लिक किया है:
दिया हुआ:
class Person
end
हमने व्यक्ति को किसी ऐसी चीज़ के रूप में परिभाषित नहीं किया है जिसका नाम या उस मामले के लिए कोई अन्य विशेषता हो सकती है।
तो अगर हम:
baby = Person.new
... और उन्हें एक नाम देने की कोशिश ...
baby.name = "Ruth"
हमें एक त्रुटि मिलती है, क्योंकि रूबीलैंड में, वस्तु का एक व्यक्ति वर्ग ऐसा कुछ नहीं है जो "नाम" ... के साथ जुड़ा या सक्षम है!
लेकिन हम दिए गए तरीकों में से किसी का भी उपयोग कर सकते हैं (पिछले उत्तरों को देखें) कहने के तरीके के रूप में, "एक व्यक्ति वर्ग ( baby
) का एक उदाहरण अब 'नाम' नामक एक विशेषता हो सकता है , इसलिए हमारे पास न केवल प्राप्त करने का एक वाक्यात्मक तरीका है और उस नाम को सेट करना, लेकिन यह हमारे लिए ऐसा करने के लिए समझ में आता है। ”
फिर, इस सवाल को थोड़ा अलग और अधिक सामान्य कोण से मारते हुए, लेकिन मुझे उम्मीद है कि इससे क्लास पर्सन के अगले उदाहरण को मदद मिलती है जो इस धागे के लिए अपना रास्ता खोज लेते हैं।
सीधे शब्दों में कहें तो यह कक्षा के लिए एक सेटर और गेट्टर को परिभाषित करेगा।
ध्यान दें कि
attr_reader :v is equivalant to
def v
@v
end
attr_writer :v is equivalant to
def v=(value)
@v=value
end
इसलिए
attr_accessor :v which means
attr_reader :v; attr_writer :v
वर्ग के लिए एक सेटर और गेट्टर को परिभाषित करने के लिए समतुल्य हैं।
इसे समझने का एक और तरीका यह है कि यह होने से कौन सा त्रुटि कोड समाप्त हो जाता है attr_accessor
।
उदाहरण:
class BankAccount
def initialize( account_owner )
@owner = account_owner
@balance = 0
end
def deposit( amount )
@balance = @balance + amount
end
def withdraw( amount )
@balance = @balance - amount
end
end
निम्नलिखित विधियाँ उपलब्ध हैं:
$ bankie = BankAccout.new("Iggy")
$ bankie
$ bankie.deposit(100)
$ bankie.withdraw(5)
निम्न विधियाँ त्रुटि देती है:
$ bankie.owner #undefined method `owner'...
$ bankie.balance #undefined method `balance'...
owner
और balance
, तकनीकी रूप से, एक विधि नहीं है , लेकिन एक विशेषता है। BankAccount वर्ग के पास नहीं है def owner
और def balance
। यदि ऐसा होता है, तो आप नीचे दिए गए दो आदेशों का उपयोग कर सकते हैं। लेकिन वे दो विधियां नहीं हैं। हालांकि, अगर आप कर सकते हैं का उपयोग विशेषताओं के रूप में यदि आप चाहते हैं का उपयोग के माध्यम से एक विधि attr_accessor
!! इसलिए शब्दattr_accessor
। गुण। एक्सेसर। यह उन विशेषताओं तक पहुँचता है जैसे आप एक विधि तक पहुँचेंगे।
जोड़ना attr_accessor :balance, :owner
आपको पढ़ने और लिखने balance
और owner
"विधि" की अनुमति देता है । अब आप अंतिम 2 विधियों का उपयोग कर सकते हैं।
$ bankie.balance
$ bankie.owner
इस मॉड्यूल के लिए एक नामित विशेषता को परिभाषित करता है, जहां नाम है symbol.id2name, एक उदाहरण चर (@name) और इसे पढ़ने के लिए एक संबंधित एक्सेस विधि बना रहा है। विशेषता सेट करने के लिए = नाम की एक विधि भी बनाता है।
module Mod
attr_accessor(:one, :two)
end
Mod.instance_methods.sort #=> [:one, :one=, :two, :two=]
एक विशेषता एक्सेसर उर्फ अट्रैक्टर को संक्षिप्त करने के लिए आपको दो फ्री मेथड देता है।
जैसे जावा में उन्हें गेटर्स और सेटर कहा जाता है।
कई जवाबों ने अच्छे उदाहरण दिखाए हैं इसलिए मैं बस संक्षिप्त ही होने जा रहा हूं।
#the_attribute
तथा
# The_attribute =
पुराने रूबी डॉक्स में हैश टैग # एक विधि का अर्थ है। इसमें एक वर्ग नाम उपसर्ग भी शामिल हो सकता है ... MyClass # my_method
मैं माणिक के लिए नया हूं और निम्नलिखित विचित्रता को समझने के लिए बस सौदा करना था। भविष्य में किसी और की मदद कर सकते हैं। अंत में जैसा कि ऊपर उल्लेख किया गया है, जहां 2 कार्य (डीवर myvar, def myvar =) दोनों को @myvar तक पहुंचने के लिए अंतर्निहित रूप से मिलते हैं, लेकिन इन विधियों को स्थानीय घोषणाओं द्वारा ओवरराइड किया जा सकता है।
class Foo
attr_accessor 'myvar'
def initialize
@myvar = "A"
myvar = "B"
puts @myvar # A
puts myvar # B - myvar declared above overrides myvar method
end
def test
puts @myvar # A
puts myvar # A - coming from myvar accessor
myvar = "C" # local myvar overrides accessor
puts @myvar # A
puts myvar # C
send "myvar=", "E" # not running "myvar =", but instead calls setter for @myvar
puts @myvar # E
puts myvar # C
end
end
विशेषताएँ वर्ग घटक हैं जिन्हें ऑब्जेक्ट के बाहर से एक्सेस किया जा सकता है। उन्हें कई अन्य प्रोग्रामिंग भाषाओं में गुणों के रूप में जाना जाता है। उनके मान "डॉट संकेतन" का उपयोग करके सुलभ हैं, जैसा कि object_name.attribute_name में है। पाइथन और कुछ अन्य भाषाओं के विपरीत, रूबी वस्तु के बाहर से सीधे उदाहरण चर को एक्सेस करने की अनुमति नहीं देती है।
class Car
def initialize
@wheels = 4 # This is an instance variable
end
end
c = Car.new
c.wheels # Output: NoMethodError: undefined method `wheels' for #<Car:0x00000000d43500>
उपरोक्त उदाहरण में, c कार वर्ग का एक उदाहरण (ऑब्जेक्ट) है। हमने ऑब्जेक्ट के बाहर से पहियों के उदाहरण चर के मूल्य को पढ़ने का असफल प्रयास किया। क्या हुआ कि रूबी ने सी ऑब्जेक्ट के भीतर पहियों नामक एक विधि को कॉल करने का प्रयास किया, लेकिन ऐसी कोई विधि परिभाषित नहीं की गई। संक्षेप में, object_name.attribute_name किसी ऑब्जेक्ट के भीतर Method_name नामक विधि को कॉल करने का प्रयास करता है। बाहर से चर चर के मूल्य का उपयोग करने के लिए, हमें उस नाम से एक इंस्टेंस विधि को लागू करने की आवश्यकता है, जो उस चर के मूल्य को वापस बुलाया जाएगा। इसे एक्सेसर विधि कहा जाता है। सामान्य प्रोग्रामिंग संदर्भ में, ऑब्जेक्ट के बाहर से एक इंस्टेंस वेरिएबल को एक्सेस करने का सामान्य तरीका एक्सेसर विधियों को लागू करना है, जिसे गेट्टर और सेटर विधियों के रूप में भी जाना जाता है।
निम्नलिखित उदाहरण में, हमने ऑब्जेक्ट के बाहर से पहियों के चर को एक्सेस करने के लिए कार क्लास में गेट्टर और सेटर के तरीकों को जोड़ा है। यह गेटर्स और सेटर्स को परिभाषित करने का "रूबी तरीका" नहीं है; यह केवल यह बताने के लिए कार्य करता है कि गेट्टर और सेटर विधियां क्या करती हैं।
class Car
def wheels # getter method
@wheels
end
def wheels=(val) # setter method
@wheels = val
end
end
f = Car.new
f.wheels = 4 # The setter method was invoked
f.wheels # The getter method was invoked
# Output: => 4
उपरोक्त उदाहरण काम करता है और समान कोड का उपयोग आमतौर पर अन्य भाषाओं में गेट्टर और सेटर विधियों को बनाने के लिए किया जाता है। हालांकि, रूबी ऐसा करने के लिए एक सरल तरीका प्रदान करती है: तीन अंतर्निर्मित विधियाँ जिन्हें अट्रर्रीडर, अट्रर_राइटर और अट्रर_एकेसर कहा जाता है। Attr_reader विधि बाहर से पठनीय एक परिवर्तनशील चर बनाता है, attr_writer इसे लेखन योग्य बनाता है, और attr_acistr इसे पठनीय और लेखन योग्य बनाता है।
उपरोक्त उदाहरण को इस तरह से फिर से लिखा जा सकता है।
class Car
attr_accessor :wheels
end
f = Car.new
f.wheels = 4
f.wheels # Output: => 4
उपरोक्त उदाहरण में, पहियों की विशेषता ऑब्जेक्ट के बाहर से पठनीय और लिखने योग्य होगी। यदि attr_accessor के बजाय, हमने attr_reader का उपयोग किया, तो यह केवल पढ़ने के लिए होगा। यदि हम attr_writer का उपयोग करते हैं, तो यह केवल लेखन होगा। वे तीन विधियां स्वयं में गेटर्स और सेटर नहीं हैं, लेकिन जब बुलाया जाता है, तो वे हमारे लिए गेट्टर और सेटर विधियां बनाते हैं। वे विधियां हैं जो गतिशील रूप से (प्रोग्रामेटिक रूप से) अन्य विधियां उत्पन्न करती हैं; जिसे मेटाप्रोग्रामिंग कहा जाता है।
पहला (लंबा) उदाहरण, जो रूबी की अंतर्निहित विधियों को नियोजित नहीं करता है, इसका उपयोग केवल तब किया जाना चाहिए जब गेट्टर और सेटर विधियों में अतिरिक्त कोड आवश्यक हो। उदाहरण के लिए, एक सेटर विधि को उदाहरण वेरिएबल के लिए मान निर्दिष्ट करने से पहले डेटा को मान्य करने या कुछ गणना करने की आवश्यकता हो सकती है।
इंस्टेंस_वर्जेबल_गेट और इंस्टेंस_वर्जेबल_सेट बिल्ट-इन तरीकों का उपयोग करके ऑब्जेक्ट के बाहर से (पढ़ें और लिखें) इंस्टेंस वेरिएबल तक पहुंचना संभव है। हालांकि, यह शायद ही कभी उचित है और आमतौर पर एक बुरा विचार है, क्योंकि इनकैप्सुलेशन को दरकिनार करके सभी प्रकार के कहर को मिटाया जाता है।
हममम। बहुत अच्छे जवाब। यहाँ उस पर मेरा कुछ सेंट है।
attr_accessor
एक सरल विधि (सफाई में मदद करता है सूखी-इंग ) ऊपर दोहराgetter and setter
तरीकों।
ताकि हम व्यावसायिक तर्क लिखने पर अधिक ध्यान केंद्रित कर सकें और बसने वालों और पाने वालों की चिंता न कर सकें।
अन्य लोगों पर attr_accessor की मुख्य कार्यक्षमता अन्य फ़ाइलों से डेटा तक पहुँचने की क्षमता है।
तो आप आमतौर पर attr_reader या attr_writer होगा, लेकिन अच्छी खबर यह है कि Ruby आपको attr_accessor के साथ इन दोनों को एक साथ संयोजित करने देता है। मैं इसके बारे में सोचता हूं कि यह मेरी विधि है क्योंकि यह अधिक अच्छी तरह से गोल या बहुमुखी है। इसके अलावा, ध्यान रखें कि रेल में, यह समाप्त हो जाता है क्योंकि यह बैक एंड में आपके लिए करता है। तो दूसरे शब्दों में: आप अन्य दो पर attr_acurer का उपयोग करने से बेहतर हैं क्योंकि आपको विशिष्ट होने के बारे में चिंता करने की ज़रूरत नहीं है, एक्सेसर इसे कवर करता है। मुझे पता है कि यह एक सामान्य स्पष्टीकरण से अधिक है लेकिन इसने मुझे एक शुरुआत के रूप में मदद की।
उम्मीद है कि इस मदद की!