उदाहरण चर: स्वयं बनाम @


179

यहाँ कुछ कोड है:

class Person
  def initialize(age)
    @age = age
  end

  def age
    @age
  end

  def age_difference_with(other_person)
    (self.age - other_person.age).abs
  end

  protected :age
end

मैं जो जानना चाहता हूं वह उपयोग करने @ageऔर विधि self.ageमें अंतर है age_difference_with

जवाबों:


260

लेखन @ageसीधे उदाहरण चर तक पहुँचता है @age। लेखन self.ageखुद को संदेश भेजने के लिए वस्तु बताता है age, जो आमतौर पर उदाहरण चर को वापस कर देगा @age- लेकिन किसी भी ageउप-वर्ग में कैसे विधि लागू की जाती है , इसके आधार पर किसी भी अन्य चीजों की संख्या कर सकता है । उदाहरण के लिए, आपके पास एक MiddleAgedSocialite वर्ग हो सकता है जो हमेशा अपनी उम्र 10 वर्ष से कम उम्र की रिपोर्ट करता है जो वास्तव में है। या अधिक व्यावहारिक रूप से, एक PersistentPerson वर्ग आलसी रूप से उस डेटा को लगातार स्टोर से पढ़ सकता है, अपने सभी स्थायी डेटा को हैश में कैश कर सकता है।


2
मैंने एक बार रेल में एक पुस्तक पढ़ी है और इस स्वयं और @ के बीच के अंतर को नहीं समझता हूं, इसलिए मुझे हमेशा अपने इंटरफेस में सेल्फ.वर_नाम का उपयोग करना चाहिए (जो कि सेटर और गेट्टर नहीं करता है) अपने डेटा को सार्वजनिक इंटरफ़ेस का उपयोग करने के लिए, मैं इसे गेट्टर और सेटर में परिभाषित करने में समय व्यतीत होता है, है ना?
सार्णव

1
... अंग्रेजी ... आप किसी भी संख्या से क्या मतलब है। मुझे वह अंतिम दो उदाहरण नहीं मिले।
user2167582

23

अंतर यह है कि यह इसके कार्यान्वयन से विधि के उपयोग को अलग कर रहा है। यदि संपत्ति के कार्यान्वयन को बदलना था - तो जन्मतिथि रखने के लिए कहें और फिर अब और जन्मतिथि के बीच के अंतर के आधार पर उम्र की गणना करें - फिर विधि के आधार पर कोड को बदलने की आवश्यकता नहीं है। यदि यह सीधे संपत्ति का उपयोग करता है, तो परिवर्तन को कोड के अन्य क्षेत्रों में प्रचार करने की आवश्यकता होगी। इस अर्थ में, क्लास द्वारा प्रदान किए गए इंटरफ़ेस का उपयोग करने की तुलना में सीधे संपत्ति का उपयोग करना अधिक नाजुक है।


15
ओह, क्योंकि self.age या तो एक उदाहरण चर या एक उदाहरण विधि को संदर्भित कर सकता है?
नोलन एमी

@। @ ... दुख की बात यह है
cc115

7

सावधान रहें जब आप एक वर्ग से वारिस Struct.newपैदा करते हैं, जो एक इंटेस्टाइज़र बनाने का एक अच्छा तरीका है ( रूबी में इनिशियलाइज़र कैसे उत्पन्न करें? )

class Node < Struct.new(:value)
    def initialize(value)
        @value = value
    end
    def show()
        p @value
        p self.value # or `p value`
    end
end 

n = Node.new(30)
n.show()

वापस होगा

30
nil

हालाँकि, जब आप इनिलाइज़र को निकालते हैं, तो यह वापस आ जाएगा

nil
30

वर्ग की परिभाषा के साथ

class Node2
    attr_accessor :value
    def initialize(value)
        @value = value
    end
    def show()
        p @value
        p self.value
    end
end

आपको कंस्ट्रक्टर प्रदान करना चाहिए।

n2 = Node2.new(30)
n2.show()

वापस होगा

30
30

उदाहरण @Prosseek के लिए धन्यवाद, मैं वर्तमान में रूबी रेल्स पर सीख रहा हूं और यह ठीक उसी तरह का व्यवहार है जिससे मुझे लगता है कि रूबी अनावश्यक रूप से जटिल है> <।
cc115

3

पहला उत्तर पूरी तरह से सही है, लेकिन एक रिश्तेदार नौसिखिया के रूप में यह मेरे लिए तुरंत स्पष्ट नहीं था कि यह क्या निहित है (स्वयं को संदेश भेजना? उह हुह ...)। मुझे लगता है कि एक छोटा उदाहरण मदद करेगा:

class CrazyAccessors
  def bar=(val)
    @bar = val - 20 # sets @bar to (input - 20)
  end
  def bar
    @bar
  end

  def baz=(value)
    self.bar = value # goes through `bar=` method, so @bar = (50 - 20)
  end

  def quux=(value)
    @bar = value     # sets @bar directly to 50
  end
end

obj  = CrazyAccessors.new
obj.baz = 50
obj.bar  # => 30
obj.quux = 50
obj.bar  # => 50

8
इस उदाहरण ने चीजों को और अधिक भ्रमित कर दिया।
Oskar Holmkratz

1
मुझे खेद है लेकिन उदाहरण के लिए मेरे लिए पर्याप्त टिप्पणी नहीं की गई है। मैं आपके तर्क का पालन नहीं कर सकता।
19

स्मॉलटाकल से आया कोई व्यक्ति कहेगा कि एक वस्तु "खुद को एक संदेश भेजती है।" कोई जो पायथन से आया था, वह कहेगा कि एक वस्तु "अपने आप में एक विधि कहती है।" भ्रमित मत हो; वे बिलकुल एक जैसे हैं। (एक शब्दार्थवादी शुद्धतावादी आपत्ति कर सकते हैं कि वे केवल डायनामिक टाइपिंग वाली भाषाओं के लिए ही हैं और C ++ वर्चुअल मेथड कॉल एक संदेश भेजने के समान नहीं है। शुद्धतावादी सही है, लेकिन यह शायद इस प्रश्न के दायरे से परे है / उत्तर।)
ग्रैंडऑपनर

मुझे उदाहरण पसंद है लेकिन कृपया कुछ और टिप्पणियां प्रदान करें जो वास्तव में हो रहा है। कोई स्पष्टीकरण के साथ पालन करने के लिए मुश्किल
CalamityAdam

2

कोई अंतर नहीं है। मुझे संदेह है कि यह सिर्फ देखने self.ageऔर other_person.ageएक-दूसरे के पास के दस्तावेजी मूल्य के लिए किया गया था ।

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

लेकिन, इस बारे में चिंता करने की संभावना नहीं है कि आखिरकार, यदि वस्तु का कार्यान्वयन बदल गया है तो अन्य तरीकों को बदलना उचित है, कुछ बिंदु पर वस्तु के भीतर एक साधारण संदर्भ ही पूरी तरह से उचित है।

किसी भी मामले में, ageसंपत्ति का अमूर्त उपयोग अभी भी स्पष्ट उपयोग की व्याख्या नहीं करता है self, क्योंकि सिर्फ सादे ageने भी एक्सेसर को आमंत्रित किया होगा।


-3

@age - निश्चित रूप से उदाहरण चर आयु है

self.age - उदाहरण का तात्पर्य संपत्ति की आयु से है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.