आज मैं self के बारे में बात करना चाहूंगा। यदि आप कुछ समय से रूबी प्रोग्रामिंग कर रहे हैं, तो आपने संभवतः self के विचार को आंतरिक कर लिया है। जब भी आप कोई प्रोग्राम पढ़ते या लिखते हैं, self आपके दिमाग में पीछे होता है।
लेकिन कम अनुभवी रूबीस्ट्स के लिए, self हैरान करने वाला हो सकता है। यह हमेशा बदलता रहता है, लेकिन यह कोड में कभी भी स्पष्ट रूप से नहीं दिखाया जाता। आपको बस पता होना चाहिए।
शुरुआती लोगों की बहुत सारी समस्याएं self को न समझने के कारण होती हैं। यदि आपने कभी किसी इंस्टेंस वेरिएबल को "खोया" है या इस बात पर हैरान हुए हैं कि मिक्सिन को कौन सा डेटा दिखाई देता है, तो ऐसा इसलिए है क्योंकि आप उस संदर्भ में self को नहीं समझते थे।
इस पोस्ट में, हम self को विभिन्न रोजमर्रा की स्थितियों में देखने जा रहे हैं।
What is self?
आपने लोगों को यह कहते सुना होगा कि रूबी में सब कुछ एक ऑब्जेक्ट है। यदि यह सच है तो इसका मतलब है कि आपके द्वारा लिखा गया हर कोड "किसी" ऑब्जेक्ट का है।
self एक विशेष वेरिएबल है जो वर्तमान में निष्पादित कोड के "मालिक" ऑब्जेक्ट की ओर इशारा करता है। रूबी self का हर जगह उपयोग करता है:
- इंस्टेंस वेरिएबल के लिए:
@myvar - मेथड और कॉन्स्टेंट लुकअप के लिए
- मेथड, क्लास और मॉड्यूल को परिभाषित करते समय।
सिद्धांत रूप में, self काफी स्पष्ट है। लेकिन व्यवहार में, मुश्किल स्थितियों का सामने आना आसान है। इसलिए मैंने यह पोस्ट लिखा।
self के उदाहरण
हम अब कई उदाहरणों के माध्यम से कदम दर कदम जाने वाले हैं। अगर पहले वाले आपको बहुत बुनियादी लगते हैं, तो बस पढ़ते रहें। वे अधिक उन्नत हो जाते हैं।
एक इंस्टेंस मेथड के अंदर
नीचे दिए गए कोड में, reflect एक इंस्टेंस मेथड है। यह उस ऑब्जेक्ट का है जिसे हमने Ghost.new के माध्यम से बनाया था। इसलिए self उस ऑब्जेक्ट की ओर इशारा करता है।
class Ghost def reflect self end end g = Ghost.new g.reflect == g # => true
एक क्लास मेथड के अंदर
इस उदाहरण के लिए, reflect Ghost का एक क्लास मेथड है। क्लास मेथड के साथ, क्लास स्वयं मेथड का "मालिक" होता है। self क्लास की ओर इशारा करता है।
class Ghost def self.reflect self end end Ghost.reflect == Ghost # => true
यह मॉड्यूल के अंदर "क्लास" मेथड के साथ उसी तरह काम करता है। उदाहरण के लिए:
module Ghost def self.reflect self end end Ghost.reflect == Ghost # => true
याद रखें, रूबी में क्लास और मॉड्यूल को ऑब्जेक्ट माना जाता है। इसलिए यह व्यवहार पहले उदाहरण में देखे गए इंस्टेंस मेथड व्यवहार से बहुत अलग नहीं है।
एक क्लास या मॉड्यूल परिभाषा के अंदर
रूबी की एक विशेषता जो इसे रेल्स जैसे फ्रेमवर्क के लिए इतना उपयुक्त बनाती है वह यह है कि आप क्लास और मॉड्यूल परिभाषा के अंदर मनमाना कोड निष्पादित कर सकते हैं। जब आप क्लास/मॉड्यूल परिभाषा के अंदर कोड डालते हैं, तो यह किसी अन्य रूबी कोड की तरह चलता है। एकमात्र वास्तविक अंतर self का मान है।
जैसा कि आप नीचे देख सकते हैं, self उस क्लास या मॉड्यूल की ओर इशारा करता है जिसे परिभाषित किया जा रहा है।
class Ghost self == Ghost # => true end module Mummy self == Mummy # => true end
मिक्सिन मेथड के अंदर
मिक्सिन किए गए मेथड self के संबंध में "सामान्य" इंस्टेंस या क्लास मेथड की तरह ही व्यवहार करते हैं। यह समझ में आता है। अन्यथा मिक्सिन उस क्लास के साथ इंटरैक्ट नहीं कर पाएगा जिसमें इसे मिक्स किया गया था।
इंस्टेंस मेथड
भले ही reflect मेथड मॉड्यूल में परिभाषित किया गया था, इसका self उस क्लास का इंस्टेंस है जिसमें इसे मिक्स किया गया था।
module Reflection def reflect self end end class Ghost include Reflection end g = Ghost.new g.reflect == g # => true
क्लास मेथड
जब हम क्लास मेथड में मिक्स करने के लिए एक क्लास को extend करते हैं, तो self सामान्य क्लास मेथड की तरह ही व्यवहार करता है।
module Reflection def reflect self end end class Ghost extend Reflection end Ghost.reflect == Ghost # => true
मेटाक्लास के अंदर
संभावना है कि आपने एक साथ कई क्लास मेथड को परिभाषित करने के लिए इस लोकप्रिय शॉर्टकट को देखा है।
class Ghost class << self def method1 end def method2 end end end
class << foo सिंटैक्स वास्तव में काफी दिलचस्प है। यह आपको एक ऑब्जेक्ट के मेटाक्लास तक पहुंचने देता है - जिसे "सिंगलटन क्लास" या "आइगेनक्लास" भी कहा जाता है। मैं भविष्य की पोस्ट में मेटाक्लास को अधिक गहराई से कवर करने की योजना बना रहा हूँ। लेकिन अभी के लिए, आपको बस यह जानने की आवश्यकता है कि मेटाक्लास वह जगह है जहां रूबी एक विशिष्ट ऑब्जेक्ट के लिए अद्वितीय मेथड को संग्रहीत करता है।
यदि आप class << foo ब्लॉक के अंदर से self तक पहुंचते हैं, तो आपको मेटाक्लास मिलता है।
class << "test" puts self.inspect end # => #<Class:#<String:0x007f8de283bd88>
किसी क्लास के बाहर
यदि आप किसी क्लास के बाहर कोड चला रहे हैं, तो रूबी अभी भी self प्रदान करता है। यह "main" की ओर इशारा करता है, जो Object का एक इंस्टेंस है:
puts self.inspect # => main