वर्ग << रूबी में आत्म मुहावरा


873

रूबीclass << self में क्या करती है ?



3
एक और सुपर अच्छा लेख यहाँ: integralist.co.uk/posts/eigenclass.html
समन मोहम्मदी

2
मैं इसे एक मॉड्यूल के अंदर देख रहा हूं, क्या यह इसे अलग बनाता है? github.com/ruby/rake/blob/master/lib/rake/rake_module.rb
विलियम एंट्रिएन

@FullDecent इससे कोई फर्क नहीं पड़ता क्योंकि रूबी में सब कुछ मॉड्यूल और कक्षाओं सहित एक वस्तु है।
एरॉन

1
देखें github.com/defunkt/metaid/blob/master/metaid.rb यह "जाहिर है Metaclasses देखकर" के साथ चला जाता viewsourcecode.org/why/hacking/seeingMetaclassesClearly.html
डगलस जी एलन

जवाबों:


912

सबसे पहले, class << fooवाक्यविन्यास fooएकल वर्ग (eigenclass) को खोलता है। यह आपको उस विशिष्ट वस्तु पर बुलाए गए तरीकों के व्यवहार को विशेषज्ञ बनाने की अनुमति देता है।

a = 'foo'
class << a
  def inspect
    '"bar"'
  end
end
a.inspect   # => "bar"

a = 'foo'   # new object, new singleton class
a.inspect   # => "foo"

अब, इस प्रश्न का उत्तर देने के लिए: एकल वर्ग को class << selfखोलता है self, ताकि वर्तमान selfवस्तु के लिए तरीकों को फिर से परिभाषित किया जा सके (जो किसी वर्ग या मॉड्यूल बॉडी के अंदर ही वर्ग या मॉड्यूल है )। आमतौर पर, इसका उपयोग वर्ग / मॉड्यूल ("स्थिर") विधियों को परिभाषित करने के लिए किया जाता है:

class String
  class << self
    def value_of obj
      obj.to_s
    end
  end
end

String.value_of 42   # => "42"

इसे शॉर्टहैंड के रूप में भी लिखा जा सकता है:

class String
  def self.value_of obj
    obj.to_s
  end
end

या इससे भी कम:

def String.value_of obj
  obj.to_s
end

जब एक फ़ंक्शन परिभाषा के अंदर, selfउस ऑब्जेक्ट को संदर्भित करता है जिसे फ़ंक्शन के साथ बुलाया जा रहा है। इस स्थिति में, class << selfउस ऑब्जेक्ट के लिए सिंगलटन क्लास खोलता है; इसका एक उपयोग एक गरीब आदमी की राज्य मशीन को लागू करना है:

class StateMachineExample
  def process obj
    process_hook obj
  end

private
  def process_state_1 obj
    # ...
    class << self
      alias process_hook process_state_2
    end
  end

  def process_state_2 obj
    # ...
    class << self
      alias process_hook process_state_1
    end
  end

  # Set up initial state
  alias process_hook process_state_1
end

इसलिए, ऊपर दिए गए उदाहरण में, प्रत्येक उदाहरण StateMachineExampleने process_hookअलियास किया है process_state_1, लेकिन ध्यान दें कि उत्तरार्द्ध में कैसे, यह फिर से परिभाषित कर सकता है process_hook( selfकेवल, अन्य StateMachineExampleउदाहरणों को प्रभावित नहीं करने के लिए) process_state_2। इसलिए, हर बार एक कॉलर processविधि को कॉल करता है (जिसे पुनर्निर्धारित कहता है process_hook), यह किस स्थिति में है, इसके आधार पर व्यवहार बदलता है।


22
@ Jörg: +1 फॉर एडिट (काश एसओ एडिट्स को उभारने की क्षमता प्रदान करता है; अच्छी तरह से)। वह वास्तव में class << selfवर्ग / मॉड्यूल विधियों को बनाने के लिए, का अधिक सामान्य उपयोग है । मैं शायद इसके उपयोग पर विस्तार करूंगा class << self, क्योंकि यह बहुत अधिक मुहावरेदार उपयोग है।
क्रिस जस्टर-यंग

4
gsub! ("eigenclass", "सिंगलटन क्लास"), आगामी विधि redmine.ruby-lang.org/repositories/revision/1?rev=27022 देखें
मार्क-आंद्रन लाफ्यून

4
यह वास्तव में a's के singleton_classबाद से aवर्ग को संदर्भित करने के बाद (बदलने के बाद inspect) वर्ग का एक अनूठा संस्करण है String। यदि यह एकल Stringवर्ग बदल रहा था तो यह अन्य सभी Stringउदाहरणों को प्रभावित करेगा । वियरडर अभी भी यही है कि यदि आप बाद में फिर Stringसे परिभाषित करने के लिए फिर से खोलते हैं , inspectतो फिर aभी नए बदलाव उठाएंगे।
ओल्ड प्रो

1
@ ओल्प्रो मैं अभी भी ईजेनक्लस नाम को पसंद करता हूं, जैसा कि (मुझे विश्वास है) मात्ज़ भी करता है। लेकिन, मैं हर किसी को खुश नहीं कर सकता, मुझे लगता है।
क्रिस जस्टर-यंग

5
मुझे अभिव्यक्ति मिलती है, "एक वस्तु एकल वर्ग खोलता है" - जिसे मैंने पहले कई बार पढ़ा है - अस्पष्ट। मेरी जानकारी के लिए, रूबी डॉक्स में कहीं भी एक वर्ग को "खोलना" परिभाषित नहीं किया गया है, भले ही हम सभी को इसका मतलब है। क्या class << selfइसका मतलब selfब्लॉक के दायरे के भीतर एकल वर्ग के बराबर मूल्य से अधिक है ?
कैरी स्वेवेलैंड

34

मैं के बारे में एक सुपर इसे आसानी से समझा पाया class << self, Eigenclassऔर तरीकों के विभिन्न प्रकार।

रूबी में, तीन प्रकार की विधियाँ हैं जिन्हें एक वर्ग पर लागू किया जा सकता है:

  1. उदाहरण के तरीके
  2. सिंगलटन के तरीके
  3. कक्षा के तरीके

इंस्टेंस मेथड और क्लास मेथड अन्य प्रोग्रामिंग लैंग्वेज में उनके होमनेम के लगभग समान हैं।

class Foo  
  def an_instance_method  
    puts "I am an instance method"  
  end  
  def self.a_class_method  
    puts "I am a class method"  
  end  
end

foo = Foo.new

def foo.a_singleton_method
  puts "I am a singletone method"
end

एक्सेस करने का एक और तरीका Eigenclass(जिसमें सिंगलटन तरीके शामिल हैं) निम्नलिखित सिंटैक्स के साथ है ( class <<):

foo = Foo.new

class << foo
  def a_singleton_method
    puts "I am a singleton method"
  end
end

अब आप एक एकल विधि को परिभाषित कर सकते हैं selfजिसके लिए Fooइस संदर्भ में स्वयं कक्षा है:

class Foo
  class << self
    def a_singleton_and_class_method
      puts "I am a singleton method for self and a class method for Foo"
    end
  end
end

4
वास्तव में सिंगलटन के तरीके और क्लास के तरीके समान हैं, दोनों ही सिंगलटन क्लास में मौजूद हैं। आप foo.singleton_class.instance_methods(false)जांचने के लिए उपयोग कर सकते हैं ।
डेमन युआन

22

आमतौर पर, उदाहरण के तरीके वैश्विक तरीके हैं। इसका मतलब है कि वे उस वर्ग के सभी उदाहरणों में उपलब्ध हैं, जिस पर उन्हें परिभाषित किया गया था। इसके विपरीत, एकल वस्तु पर एक एकल विधि लागू की जाती है।

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

यदि एक एकल ऑब्जेक्ट के भीतर कई सिंगलटन विधियों को परिभाषित किया गया है, तो वे सभी एक ही मेटाक्लास में संग्रहीत होते हैं।

class Zen
end

z1 = Zen.new
z2 = Zen.new

class << z1
  def say_hello
    puts "Hello!"
  end
end

z1.say_hello    # Output: Hello!
z2.say_hello    # Output: NoMethodError: undefined method `say_hello'…

उपरोक्त उदाहरण में, क्लास << z1 z1 ऑब्जेक्ट के मेटाक्लास को इंगित करने के लिए वर्तमान स्व को बदलता है; फिर, यह मेटाक्लस के भीतर say_hello पद्धति को परिभाषित करता है।

कक्षाएं भी ऑब्जेक्ट्स हैं (अंतर्निहित वर्ग का उदाहरण जिसे क्लास कहा जाता है)। क्लास के तरीके क्लास ऑब्जेक्ट से जुड़े सिंगलटन तरीकों से ज्यादा कुछ नहीं हैं।

class Zabuton
  class << self
    def stuff
      puts "Stuffing zabuton…"
    end
  end
end

सभी वस्तुओं में मेटाक्लासेस हो सकते हैं। इसका मतलब है कि कक्षाओं में मेटाक्लासेस भी हो सकते हैं। उपरोक्त उदाहरण में, वर्ग << स्वयं को संशोधित करता है इसलिए यह Zabuton वर्ग के मेटाक्लास की ओर इशारा करता है। जब कोई विधि स्पष्ट रिसीवर के बिना परिभाषित की जाती है (जिस वर्ग / वस्तु पर विधि को परिभाषित किया जाएगा), यह स्पष्ट रूप से वर्तमान दायरे के भीतर परिभाषित किया जाता है, अर्थात स्वयं का वर्तमान मूल्य। इसलिए, सामान विधि को Zabuton वर्ग के मेटाक्लस के भीतर परिभाषित किया गया है। उपरोक्त उदाहरण एक वर्ग विधि को परिभाषित करने का एक और तरीका है। IMHO, वर्ग विधियों को परिभाषित करने के लिए def self.my_new_clas_method सिंटैक्स का उपयोग करना बेहतर है, क्योंकि यह कोड को समझना आसान बनाता है। उपरोक्त उदाहरण को शामिल किया गया था इसलिए हम समझते हैं कि जब हम कक्षा में आते हैं तो क्या होता है << आत्म वाक्य रचना।

इस पोस्ट पर रूबी क्लासेस के बारे में अतिरिक्त जानकारी पाई जा सकती है ।


15

क्या वर्ग << बात करता है:

class Hi
  self #=> Hi
  class << self #same as 'class << Hi'
    self #=> #<Class:Hi>
    self == Hi.singleton_class #=> true
  end
end

[यह self == thing.singleton_class अपने ब्लॉक के संदर्भ में बनाता है]


बात क्या है। सिंगिंगटन_क्लास?

hi = String.new
def hi.a
end

hi.class.instance_methods.include? :a #=> false
hi.singleton_class.instance_methods.include? :a #=> true

hiवस्तु अपने #methodsसे #singleton_class.instance_methodsऔर फिर अपने से विरासत में मिलती है #class.instance_methods
यहाँ हम दे दिया hiहै सिंगलटन वर्ग उदाहरण विधि :a। यह वर्ग << हाय के बजाय किया जा सकता था ।
hi's #singleton_classहै सभी उदाहरण के तरीकों hiकी #classहै, और संभवतः कुछ अधिक ( :aयहाँ)।

[चीज़ के उदाहरण के तरीके #class और #singleton_class सीधे चीज़ पर लागू किया जा सकता है। जब रूबी बात को देखता है। एक, यह पहली बार दिखता है: thing.singleton_class.instance_methods और फिर thing.class.instance_methods] में एक विधि परिभाषा


वैसे - वे वस्तु की फोन सिंगलटन वर्ग == metaclass == eigenclass


3

सब सिंगलटन विधि एक ऐसी विधि है जिसे केवल एक ही वस्तु के लिए परिभाषित किया जाता है।

उदाहरण:

class SomeClass
  class << self
    def test
    end
  end
end

test_obj = SomeClass.new

def test_obj.test_2
end

class << test_obj
  def test_3
  end
end

puts "Singleton's methods of SomeClass"
puts SomeClass.singleton_methods
puts '------------------------------------------'
puts "Singleton's methods of test_obj"
puts test_obj.singleton_methods

सिंगलटन के सिंगलटन के तरीके

परीक्षा


सिंगलटन के टेस्ट_बज के तरीके

test_2

test_3


1

वास्तव में यदि आप अपनी रूबी परियोजनाओं के लिए कोई सी एक्सटेंशन लिखते हैं तो वास्तव में एक मॉड्यूल विधि को परिभाषित करने का केवल एक ही तरीका है।

rb_define_singleton_method

मुझे पता है कि यह स्व-व्यवसाय बस सभी प्रकार के अन्य प्रश्नों को खोलता है ताकि आप प्रत्येक भाग को खोजकर बेहतर कर सकें।

वस्तुएं पहले।

foo = Object.new

क्या मैं फू के लिए एक विधि बना सकता हूं?

ज़रूर

def foo.hello
 'hello'
end

इसके साथ मैं क्या करूं?

foo.hello
 ==>"hello"

बस एक और वस्तु।

foo.methods

आपको सभी ऑब्जेक्ट विधियां मिलती हैं और साथ ही आपका नया।

def foo.self
 self
end

foo.self

बस फू वस्तु।

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

सिंगलटन, क्लास, मॉड्यूल, सेल्फ, ऑब्जेक्ट, और इगेंक्लास को लाया गया था लेकिन रूबी ऑब्जेक्ट मॉडल का नाम नहीं देता है। यह मेटाक्लस की तरह अधिक है। रिचर्ड या __वह आपको यहां विचार दिखाता है। http://viewsourcecode.org/why/hacking/ ToursMetaclassesClearly.html और यदि आपको उड़ाता है तो खोज में रूबी ऑब्जेक्ट मॉडल देखने का प्रयास करें। दो वीडियो जो मुझे YouTube पर पता हैं, वे हैं डेव थॉमस और पीटर कूपर। वे उस अवधारणा को भी समझाने की कोशिश करते हैं। डेव को इसे प्राप्त करने में लंबा समय लगा इसलिए चिंता न करें। मैं अब भी इस पर काम कर रहा हूं। मैं और यहाँ क्यों रहूँगा? आपके प्रश्न के लिए धन्यवाद। मानक पुस्तकालय का भी अवलोकन करें। इसमें FYI के रूप में एक सिंगलटन मॉड्यूल है।

यह बहुत अच्छा है। https://www.youtube.com/watch?v=i4uiyWA8eFk

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