Ruby Language
सिंगलटन क्लास
खोज…
वाक्य - विन्यास
- 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