10
class << self 
attr_accessor :n, :totalX, :totalY 
end 

क्लास इंस्टेंस चर को परिभाषित करने के लिए उपरोक्त वाक्यविन्यास का उपयोग किया जाता है। लेकिन जब मैं सोचता हूं कि वाक्यविन्यास का क्या अर्थ है, तो यह मुझे कोई समझ नहीं आता है, इसलिए मुझे आश्चर्य है कि इस प्रकार का वाक्यविन्यास किसी अन्य प्रकार की परिभाषाओं के लिए उपयोग किया जाता है। भ्रम की स्थिति यहाँ से मेरी बात यह है:रूबी में सिंटैक्स के कोई संबंधित अनुप्रयोग हैं: कक्षा << स्वयं ... अंत

class << self 

संलग्न ऑपरेटर सामान्य रूप से "जोड़ने क्या बाईं तरफ वस्तु के अधिकार पर है" का मतलब है। लेकिन इस ब्लॉक के संदर्भ में, यह "इस ब्लॉक की सामग्री को उदाहरण के बजाए कक्षा के उदाहरण की परिभाषा में डाल" कैसे जोड़ता है?

इसी कारण मैं क्यों एक संदर्भ में वर्ग < < स्वयं वर्ग उदाहरण वैरिएबल निर्धारित कर सकते करने के लिए के रूप में, जबकि एक अन्य में यह इस तरह यहाँ के रूप में वर्ग चर बनाने का लगता है संदेह में हूँ के लिए:

class Point 
    # Instance methods go here 
    class << self 
    # Class methods go here 
    end 
end 

उत्तर

18

रूबी में आप मौजूदा कक्षाओं को फिर से खोल सकते हैं और विधियां जोड़ सकते हैं। यही कारण है, आप कह सकते हैं:

class Foo 
    def bob 
    return "hello from bob" 
    end 
end 

इन तरीकों Foo श्रेणी का एक आंतरिक शब्दकोश (शायद एक उदाहरण चर) में कहीं संग्रहीत हो (जो सिर्फ Class श्रेणी का एक उदाहरण है और इसलिए है उदाहरण चर)

लेकिन आश्चर्य की बात बात यह है कि आप भी उदाहरणों करने के तरीकों में जोड़ सकते हैं, है मौजूदा वस्तुओं की

foo = Foo.new 
foo2 = Foo.new 

def foo.fred 
    return "I am fred" 
end 


foo.fred #=> "I am fred" 
foo2.fred #=> NoMethodError 

लेकिन यह विधि वास्तव में संग्रहीत कहां है?

बाहर कर देता है रूबी पर्दे के पीछे एक नया वर्ग पैदा करता है (कभी कभी सिंगलटन वर्ग, metaclass बुलाया या eigenclass) जो विरासत पदानुक्रम Foo स्तरीय और उसके उदाहरण के बीच में डाला जाता है।

तो विरासत रिश्ता है कि तरह लग रहा है:

foo < (eigenclass of foo) < Foo < Class 

(अगर आप कहते हैं कि foo।सुपरक्लास आपको सिंगलटन क्लास नहीं दिखाई देगा)

class << X -सिंटाक्स इस विशेष श्रेणी में जाने का एक तरीका है, ताकि आप इसे सीधे तरीके से कुशल बना सकें। निम्नलिखित कोड ब्लॉक बिल्कुल बराबर हैं:

def foo.bar 
    return "xy" 
end 

# is exactly the same as 

class << foo 
    def bar 
    return "xy" 
    end 
end 

तो class Foo < Bar और class << Foo के बीच समानता आकस्मिक नहीं है, विरासत दोनों में चल रही है।

रूबी में याद करने के लिए बात "ऊपर एक्स के metaclass खोलने" के रूप में class << X की

लगता है कि कक्षाओं में खुद को सिर्फ वस्तुओं रहे है। (कक्षा Class के उदाहरण) इसलिए यदि आप कहते हैं:

class Foo 
    class << self 
    def k 
     return "x" 
    end 
    end 
end 

(self इस कोड ब्लॉक में Foo के लिए बाध्य है) तो k एक उदाहरण विधि Foo की eigenclass की है, जो इसे एक वर्ग विधि बनाता है कि '- Foo

सभी इस chapter about classes of the Pickaxe में अधिक स्पष्ट रूप से समझाया गया है (वेब ​​संस्करण चित्र शामिल नहीं है, दुर्भाग्य से) और _whys Seeing Metaclasses Clearly

2

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

मैं संकेत देता हूं कि नोटेशन थोड़ा अजीब है, हालांकि।

+0

ठीक है के लिए यह देखने का एक अच्छा तरीका है - कक्षा वास्तव में एक शब्दकोश है। लेकिन वास्तव में आपने उत्तर दिया कि मैंने अपना आखिरी उदाहरण जोड़ा है, जहां एक और संदर्भ में एक ही sytax (पुस्तक के अनुसार मैं पढ़ रहा हूं) वर्ग उदाहरण विधियों के बजाय कक्षा विधियों का उत्पादन करता है। नीचे बिंदु पर पॉइंट क्लास उदाहरण क्लास विधि में क्यों होता है जबकि शीर्ष पर attr_accessor आपको क्लास-इंस्टेंस स्तर पर विशेषता देता है? –

+0

वास्तव में आपके द्वारा दिए गए स्पष्टीकरण का उपयोग करके मैं अपनी पिछली टिप्पणी में प्रश्न का उत्तर दे सकता हूं - attr_accessor विधि क्लास क्लास की instance_variable_set और instance_variable_get विधियों को कॉल करती है। आम तौर पर उनको परिणाम चर बनाने के परिणामस्वरूप होंगे क्योंकि हम क्लास डिक्शनरी में जोड़ रहे हैं, जैसा कि आपने इसे रखा है, हम क्लास इंस्टेंस वेरिएबल्स बना रहे हैं। ठीक है, मुझे लगता है कि मुझे अब मिल गया है। धन्यवाद। –

+1

-1 भ्रामक, वर्ग के बाद से << x ... अंत वास्तव में एक्स के मेटाक्लास को जानकारी जोड़ता है, एक्स की कक्षा नहीं। – rampion

1

यह वास्तव में "संलग्न" ऑपरेटर के संदर्भ में इसके बारे में सोचने में भ्रमित है। इसे देखने का एक बेहतर तरीका यह है कि class Foo क्लास फू खोलता है, यानी, यह क्लास ऑब्जेक्ट फू को 'स्वयं' सेट करता है, यदि आवश्यक हो तो इसे बनाते हैं, इसलिए class << self वर्तमान 'स्वयं' ऑब्जेक्ट का eigenclass खोलता है। ध्यान दें कि यह किसी भी ऑब्जेक्ट बार के लिए स्वयं तक सीमित नहीं है, आप उस ऑब्जेक्ट के eigenclass को खोलने के लिए कक्षा < < बार कह सकते हैं।

class A 
    def hello 
    print "hello world" 
    end 
end 

a = A.new 
b = A.new 

class << a 
    def goodbye 
    print "goodbye cruel world" 
    end 
end 

a.hello 
b.hello 
a.goodbye 
b.goodbye 
संबंधित मुद्दे