सवाल Eigenclass self.class के बराबर क्यों नहीं है, जब यह इतना समान दिखता है?


मैंने कहीं मेमो याद किया है, और मुझे उम्मीद है कि आप इसे मुझे समझाएंगे।

किसी वस्तु का eigenclass अलग क्यों है self.class?

class Foo
  def initialize(symbol)
    eigenclass = class << self
      self
    end
    eigenclass.class_eval do
      attr_accessor symbol
    end
  end
end

तर्क की मेरी ट्रेन जो eigenclass के बराबर है class.self बल्कि सरल है:

class << self उदाहरण विधियों की बजाय कक्षा विधियों की घोषणा करने का एक तरीका है। यह एक शॉर्टकट है def Foo.bar

तो कक्षा वस्तु के संदर्भ में, लौट रहा है self के समान होना चाहिए self.class। यह है क्योंकि class << self सेट होगा self सेवा मेरे Foo.class कक्षा विधियों / विशेषताओं की परिभाषा के लिए।

क्या मैं बस उलझन में हूँ? या, क्या यह रूबी मेटा प्रोग्रामिंग की एक चुस्त चाल है?


76
2017-10-27 13:31


मूल




जवाब:


class << self वर्ग विधियों की घोषणा करने का एक तरीका है (हालांकि इसे इस तरह इस्तेमाल किया जा सकता है)। शायद आपने कुछ उपयोग देखा है जैसे:

class Foo
  class << self
    def a
      print "I could also have been defined as def Foo.a."
    end
  end
end

यह काम करता है, और इसके बराबर है def Foo.a, लेकिन जिस तरह से यह काम करता है वह थोड़ा सूक्ष्म है। रहस्य यह है कि self, उस संदर्भ में, वस्तु को संदर्भित करता है Foo, जिसका वर्ग एक अद्वितीय, अज्ञात उप-वर्ग है Class। इस सबक्लास को बुलाया जाता है Fooकी eigenclass। इसलिए def a बुलाया एक नई विधि बनाता है a में Fooसामान्य विधि कॉल सिंटैक्स द्वारा सुलभ, eigenclass: Foo.a

अब एक अलग उदाहरण देखें:

str = "abc"
other_str = "def"

class << str
  def frob
    return self + "d"
  end
end

print str.frob # => "abcd"
print other_str.frob # => raises an exception, 'frob' is not defined on other_str

यह उदाहरण आखिरी के जैसा ही है, हालांकि पहले इसे बताना मुश्किल हो सकता है। frob परिभाषित किया गया है, पर नहीं String वर्ग, लेकिन eigenclass पर str, का एक अद्वितीय अज्ञात उपclass String। इसलिए str एक frob विधि, लेकिन के उदाहरण String सामान्य में नहीं। हम स्ट्रिंग के ओवरराइड विधियों को भी प्राप्त कर सकते थे (कुछ मुश्किल परीक्षण परिदृश्यों में बहुत उपयोगी)।

अब हम आपके मूल उदाहरण को समझने के लिए सुसज्जित हैं। के भीतर Fooप्रारंभिक विधि है, self वर्ग को संदर्भित नहीं करता है Foo, लेकिन कुछ विशेष रूप से उदाहरण का Foo। इसका इग्नक्लास एक उप-वर्ग है Foo, लेकिन यह नहीं है Foo; यह नहीं हो सकता है, या फिर दूसरे उदाहरण में हमने जो चाल देखी वह काम नहीं कर सका। तो अपना उदाहरण जारी रखने के लिए:

f1 = Foo.new(:weasels)
f2 = Foo.new(:monkeys)

f1.weasels = 4 # Fine
f2.monkeys = 5 # Also ok
print(f1.monkeys) # Doesn't work, f1 doesn't have a 'monkeys' method.

उम्मीद है की यह मदद करेगा।


114
2017-10-27 13:59



प्रत्येक उदाहरण है कक्षा बनाई गई कक्षा का अज्ञात उप-वर्ग है। एफ 1 की कक्षा फू का अज्ञात उप-वर्ग है, फू का वर्ग कक्षा का अज्ञात उप-वर्ग है। - David Seiler
अच्छा जवाब :) बहुत से लोग इसे स्पष्ट रूप से समझते नहीं हैं जैसा आप करते हैं। - horseyguy
जब तक मैं आपका जवाब नहीं पढ़ता तब तक इसे वास्तव में कभी नहीं समझा! :) - Nikki Erwin Ramirez
F1 के वास्तविक उदाहरण से, एफ 1 का eigenclass अलग-अलग, अवधारणात्मक रूप से अलग कैसे होता है। यदि एफ 1 एकमात्र ऐसा उदाहरण है जिसे कभी भी अपने ईजिनक्लास के तरीकों तक पहुंच प्राप्त होगी, तो क्या एफ 1 और इसके ईजेनक्लास प्रकार के टूटने के बीच अंतर नहीं है? - elju
@elju हाँ, थोड़े। वास्तव में महत्वपूर्ण भेद "फू" और "एफ 1 के ईजेनक्लास" के बीच है; अगर आपको वह मिल गया है, तो आप शायद ठीक हैं। - David Seiler


सबसे सरल जवाब: eigenclass को तत्काल नहीं किया जा सकता है।

class F
 def eigen
  class << self 
   self
  end
 end
end
F.new.eigen.new #=> TypeError: can't create instance of virtual class

44
2017-11-16 16:09



आपके पास इस वेबसाइट पर केवल 1 बिंदु हो सकता है, लेकिन मुझे आपको और आपकी शैली पसंद है। - horseyguy
सहमत डब्ल्यू / banister; यह एक अच्छा जवाब है - Christopher Scott
दिलचस्प जानकारी, लेकिन सवाल का जवाब न दें - Alexey
यह एक बेहद अंतर्दृष्टिपूर्ण और सहायक टिप्पणी है IFF ने पहले से ही @ डेविडसेलर के उत्तर को पढ़ लिया है। - Jazz
यहां थियो पावर उठाए गए अपवाद का प्रदर्शन कर रही है। - New Alexandria


येहुदा काट्ज़ उपनिवेशों को समझाने का एक बहुत अच्छा काम करता है "रुबी में मेटाप्रोग्रामिंग: यह सब स्वयं के बारे में है"


11
2017-12-21 01:38



उपशीर्षक या ... subtleties? ;) - horseyguy
doh :) यह पता लगाने के लिए धन्यवाद, अब तय है। - Pete Hodgson
वास्तव में तय नहीं है - Kamil Lelonek