2011-07-12 26 views
8

संभव डुप्लिकेट:
What is the difference between Ruby and Python versions of“self”?रूबी के आत्म बनाम अजगर के आत्म

रूबी और पायथन समान भाषाओं दोनों एक self कीवर्ड विभिन्न स्थितियों में इस्तेमाल होती है। self प्रत्येक भाषा में क्या मतलब है, और अंतर क्या हैं?

+6

पायथन में 'स्वयं' कीवर्ड नहीं है। यह केवल सम्मेलन द्वारा उपयोग किया जाता है। –

उत्तर

8

पायथन के बारे में मैं आपको कुछ नया नहीं बता सकता। self पारंपरिक रूप से विधि के पहले पैरामीटर के रूप में पारित किया गया है, जैसा कि पीएसटी ने कहा था। Python docs

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

क्रुबी (या 'एमआरआई') में कुछ ऐसा ही है जो हुड के तहत होता है।(मॉड्यूल/कक्षा/सिंगलटन) एक रूबी वर्ग पर तरीकों का उपयोग कर

  • rb_define_method (उदाहरण)
  • rb_define_singleton_method (सिंगलटन वर्ग)
  • rb_define_module_function (वर्ग/मॉड्यूल)
द्वारा हर सी विस्तार परिभाषित कर सकते हैं

वास्तविक कार्यान्वयन फ़ंक्शन हमेशा पाइथन मुहावरे के समानता में, उनके पहले तर्क के रूप में VALUE self लेते हैं। इन मामलों में self, वस्तु दृष्टान्त इस विशेष संदेश भेज दिया गया है को संदर्भित करता है यानी अगर आप

person = Person.new 
person.do_sth 

है और do_sth सी में लागू किया जाना होगा, फिर वहाँ एक इसी सी समारोह

VALUE 
person_do_sth(VALUE self) { 
    //do something 
    return self; 
} 
होगा

हर तरह के कार्यान्वयन है, जो तथ्य यह है कि हर विधि कॉल या संदेश (स्मालटाक की भाषा से चिपक) भेजा से संबंधित एक VALUE (एक रूबी वस्तु की सी प्रतिनिधित्व) वापस जाने के लिए एक वापसी मान है माणिक। रुबी में void फ़ंक्शन जैसी कोई चीज़ नहीं है।

हालांकि हमें निम्न स्तर के सी कोड में self पास करने की आवश्यकता है, आपको रूबी कोड में ऐसा करने की आवश्यकता नहीं है, रूबी आपके लिए इसका ख्याल रखती है। स्वयं का वर्तमान मूल्य वर्तमान धागे संदर्भ में आंतरिक रूप से संग्रहीत किया जाता है जिसे निष्पादित किया जाता है, इसलिए self का अस्तित्व दिया जाता है, संदेश "स्वयं" हमेशा किसी वस्तु का मूल्यांकन करेगा।

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

puts "#{self} - declared in global scope" # the 'top self' aka 'main' 
class << self 
    puts "#{self} - 'main's singleton class" # main's singleton or 'eigenclass' 
end 

puts "Starting to interpret class A code" 

class A 
    puts "#{self} - When do I get executed!?" # self is class A 

    class << self 
    puts "#{self} - And me!?" # now A's singleton class 
    def a # declaring method in class's singleton class results in class method 
     puts "#{self} - declared in singleton class" # it's A 
    end 
    end 

    def self.b 
    puts "#{self} - declared in class method" # self is class A again -> class method 
    class << self 
     puts "#{self} - declared in Class A's singleton class" # now it's Class A's singleton class 
    end 
    end 

    def c 
    puts "#{self} - declared in instance method" # self is instance of A 
    class << self 
     puts "#{self} - declared in instance's singleton class" # now it's the A instance's singleton class 
    end 
    end 

end 

puts "All so far has happened simply by interpreting A's code" 

a = A.new 
A.a 
A.b 
a.c 

आप एक विधि/फोन self के लिए किसी भी संदर्भ से एक संदेश भेजना चाहते हैं, तो आप या तो स्पष्ट रूप ऐसा कर सकता है (उदाहरण के लिए self.method) या आप रिसीवर के रूप में self छोड़ देते हैं - तो , सम्मेलन द्वारा, संदेश का निहित रिसीवर self होगा।

इसके लिए एक दिलचस्प साइड नोट रूबी की private विधियों की व्याख्या है, जो कि अलग है। private की जावा धारणा से। रूबी के निजी तरीकों से

def a 
    self.b 
end 

विधि एक जगह एक अपवाद उठाएंगे, जबकि, केवल संदेश एक अंतर्निहित रिसीवर के रूप में self का उपयोग कर भेज कर प्रतिदेय हैं अर्थात

class A 

    def a 
    b 
    end 

    private 

    def b 
    puts "I'm private" 
    end 
end 

a = A.new 
a.a # => I'm private 

काम करता है। इसका तात्पर्य है कि जावा

class A { 
    private boolean compareUs(A a1, A a2) { ... } 

    public boolean equals(A a1, A a2) { 
     return (a1.compareUs() == a2.compareUs()); 
    } 
} 

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

अंत में, चीजों को थोड़ा और जटिल करने के लिए, instance_eval और class_eval फ़ंक्शंस निष्पादन के दौरान self के मान को भी बदल देगा।

+1

अच्छाई। क्या एक उपन्यास;) –

+0

बहुत बढ़िया जवाब। धन्यवाद :) –

+0

"वापसी (a1.compareUs() == a2.compareUs())" वास्तव में? comparUs() विधि 2 पैरामीटर की आवश्यकता है – hihell

14

रूबी और पायथन वास्तव में बहुत अलग भाषाओं हैं, भले ही रूबी एक वाक्य रचना कि अजगर की तरह लग रहे करने के लिए लिखा जा सकता है (end कीवर्ड के शामिल किए जाने के साथ) ;-)

है (हालांकि वे कई समानताएं को साझा करते हैं)

रुबी संदेश-आधारित है (यह छोटे-छोटे -80 से प्रभावित था) और "संदेश" वस्तुओं को भेजे जाते हैं। रुबी किसी दिए गए दायरे के लिए निहित रिसीवर (स्पष्ट रूप से self के रूप में जाना जाता है) का समर्थन करता है। रूबी selfएक चर नहीं है, बल्कि एक अभिव्यक्ति है जो वर्तमान ऑब्जेक्ट संदर्भ का मूल्यांकन करती है।

पायथन संपत्ति आधारित है (मुझे पता है कि एक बेहतर शब्द की कमी के लिए) और इस प्रकार एसईएलएफ और जावास्क्रिप्ट के समान ही है क्योंकि कार्यों को सीधे निष्पादित किया जाता है (संदेशों को पारित करने के बजाए)। पायथन के पास self कीवर्ड नहीं है और यह केवल सम्मेलन है कि selfके रूप में विधि के पहले पैरामीटर का नाम उपयोग किया जाता है - इस प्रकार पाइथन वर्तमान ऑब्जेक्ट संदर्भ के आसपास गुजरता है।

हैप्पी कोडिंग।

9

पायथन में, my_instance.a_method(an_argument)MyClass.a_method(my_instance, an_argument) के लिए सिर्फ लघुरूप है। इस प्रकार MyClass.a_method की परिभाषा दो पैरामीटर लेना चाहिए:

class MyClass(object): 
    def a_method(self, an_argument): 
     print self # self (the instance) is available in the method 

रूप pst कहा, चर नाम self के उपयोग सिर्फ एक सम्मेलन है। आप समान रूप से

class MyClass(object): 
    def a_method(this_instance, an_argument): 
     print this_instance 

और सबकुछ एक ही काम करेगा ... लेकिन ऐसा मत करो।