खोज…


वाक्य - विन्यास

  • singleton_class = वर्ग << ऑब्जेक्ट; आत्म अंत

टिप्पणियों

सिंगलटन वर्गों के पास केवल एक उदाहरण है: उनकी संबंधित वस्तु। इसे रूबी के ObjectSpace को क्वेरी करके सत्यापित किया जा सकता है:

instances = ObjectSpace.each_object object.singleton_class

instances.count            # => 1
instances.include? object  # => true

< का उपयोग करते हुए, उन्हें ऑब्जेक्ट के वास्तविक वर्ग के उपवर्ग होने के लिए भी सत्यापित किया जा सकता है:

object.singleton_class < object.class  # => true

संदर्भ:

परिचय

रूबी में तीन प्रकार की वस्तुएँ हैं:

  • क्लास और मॉड्यूल जो क्लास क्लास या क्लास मॉड्यूल के उदाहरण हैं।
  • वर्गों के उदाहरण।
  • सिंगलटन क्लासेस।

प्रत्येक वस्तु में एक वर्ग होता है जिसमें उसके तरीके होते हैं:

class Example
end

object = Example.new

object.class  # => Example
Example.class # => Class
Class.class   # => Class

वस्तुओं में स्वयं विधियाँ नहीं हो सकती हैं, केवल उनकी कक्षा हो सकती है। लेकिन सिंगलटन क्लासेस के साथ, अन्य सिंगलटन क्लासेस सहित किसी भी ऑब्जेक्ट में तरीकों को जोड़ना संभव है।

def object.foo
  :foo
end
object.foo #=> :foo

foo को सिंगलटन क्लास ऑफ़ object पर परिभाषित किया गया है। अन्य Example उदाहरण foo जवाब नहीं दे सकते हैं।

रूबी मांग पर एकल वर्ग बनाता है। उन्हें एक्सेस करना या उनके तरीकों को जोड़ना रूबी को उन्हें बनाने के लिए मजबूर करता है।

सिंगलटन वर्ग तक पहुँचना

किसी वस्तु का सिंगलटन वर्ग प्राप्त करने के दो तरीके हैं

  • singleton_class विधि।
  • किसी वस्तु के एकल वर्ग को फिर से खोलना और self वापस करना।
object.singleton_class

singleton_class = class << object
  self
end

सिंगलटन क्लासेस में एक्सेसिंग इंस्टेंस / क्लास वेरिएबल्स

सिंगलटन वर्ग अपनी वस्तु के साथ अपने उदाहरण / वर्ग चर साझा करते हैं।

class Example
  @@foo = :example
end

def Example.foo
  class_variable_get :@@foo
end

Example.foo #=> :example

class Example
  def initialize
    @foo = 1
  end

  def foo
    @foo
  end
end

e = Example.new

e.instance_eval <<-BLOCK
  def self.increase_foo
    @foo += 1
  end
BLOCK

e.increase_foo
e.foo #=> 2

उनके उदाहरण / वर्ग चर लक्ष्य के आसपास ब्लॉक। में एक ब्लॉक का उपयोग कर उदाहरण या वर्ग चर को एक्सेस करना class_eval या instance_eval संभव नहीं है। एक स्ट्रिंग को class_eval या class_variable_get का उपयोग करना समस्या के आसपास काम करता है।

class Foo
  @@foo = :foo
end

class Example
  @@foo = :example 

  Foo.define_singleton_method :foo do
    @@foo
  end
end

Foo.foo #=> :example

सिंगलटन वर्ग का विरासत

उपवर्गों ने उपवर्गों को सिंगलटन क्लास भी कहा

class Example
end

Example.singleton_class #=> #<Class:Example>

def Example.foo
  :example
end

class SubExample < Example
end

SubExample.foo #=> :example

SubExample.singleton_class.superclass #=> #<Class:Example>

एक मॉड्यूल का विस्तार या शामिल करना सिंग्लटन क्लास का विस्तार नहीं करता है

module ExampleModule
end

def ExampleModule.foo
  :foo
end

class Example
  extend ExampleModule
  include ExampleModule
end

Example.foo #=> NoMethodError: undefined method

संदेश एकल वर्ग के साथ प्रचार

उदाहरणों में एक विधि नहीं होती है जो वे केवल डेटा ले जाते हैं। हालाँकि हम किसी भी वस्तु के लिए एक एकल वर्ग को परिभाषित कर सकते हैं जिसमें एक वर्ग का उदाहरण भी शामिल है।

जब किसी वस्तु को एक संदेश दिया जाता है (विधि कहा जाता है) रूबी पहले जांच लेती है कि क्या उस वस्तु के लिए एक एकल वर्ग को परिभाषित किया गया है और यदि वह उस संदेश का उत्तर दे सकता है अन्यथा रूबी उदाहरण की कक्षा की पूर्वजों की श्रृंखला की जाँच करता है और उस पर चलता है।

class Example
  def foo
    :example
  end
end

Example.new.foo #=> :example

module PrependedModule
  def foo
    :prepend
  end
end

class Example
  prepend PrependedModule
end

Example.ancestors #=> [Prepended, Example, Object, Kernel, BasicObject]
e = Example.new
e.foo #=> :prepended

def e.foo
  :singleton
end

e.foo #=> :singleton

रिओपनिंग (बंदर पैचिंग) सिंगलटन क्लासेस

सिंगलटन क्लास को फिर से खोलने के तीन तरीके हैं

  • एक class_eval वर्ग पर class_eval का उपयोग करना।
  • class << ब्लॉक का उपयोग करना।
  • सीधे ऑब्जेक्ट के सिंगलटन वर्ग पर एक विधि को परिभाषित करने के लिए def का उपयोग करना
class Example
end

Example.singleton_class.class_eval do
  def foo
    :foo
  end
end

Example.foo #=> :foo

class Example
end

class << Example
  def bar
    :bar
  end
end

Example.bar #=> :bar

class Example
end

def Example.baz
  :baz
end

Example.baz #=> :baz

प्रत्येक वस्तु में एक एकल वर्ग होता है जिसे आप एक्सेस कर सकते हैं

class Example
end
ex1 = Example.new
def ex1.foobar
  :foobar
end
ex1.foobar #=> :foobar

ex2 = Example.new
ex2.foobar #=> NoMethodError

एकल वर्ग

सभी ऑब्जेक्ट एक वर्ग के उदाहरण हैं। हालाँकि, यह पूरी सच्चाई नहीं है। रूबी में, प्रत्येक वस्तु में कुछ हद तक छिपा हुआ एकल वर्ग भी होता है

यह वही है जो विधियों को व्यक्तिगत वस्तुओं पर परिभाषित करने की अनुमति देता है। सिंगलटन क्लास ऑब्जेक्ट और उसके वास्तविक वर्ग के बीच बैठता है, इसलिए उस पर परिभाषित सभी तरीके उस ऑब्जेक्ट के लिए उपलब्ध हैं, और केवल उस ऑब्जेक्ट के लिए।

object = Object.new

def object.exclusive_method
  'Only this object will respond to this method'
end

object.exclusive_method
# => "Only this object will respond to this method"

Object.new.exclusive_method rescue $!
# => #<NoMethodError: undefined method `exclusive_method' for #<Object:0xa17b77c>>

ऊपर के उदाहरण को define_singleton_method का उपयोग करके लिखा जा सकता है:

object.define_singleton_method :exclusive_method do
  "The method is actually defined in the object's singleton class"
end

जो object के singleton_class पर विधि को परिभाषित करने के समान है:

# send is used because define_method is private
object.singleton_class.send :define_method, :exclusive_method do
  "Now we're defining an instance method directly on the singleton class"
end

रूबी की कोर एपीआई के हिस्से के रूप में singleton_class के अस्तित्व से पहले, सिंगलटन क्लासेस को मेटाक्लासेस के रूप में जाना जाता था और इसे निम्नलिखित मुहावरों के माध्यम से एक्सेस किया जा सकता है:

class << object
  self  # refers to object's singleton_class
end


Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow