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


85

क्या रूबी में एकल वर्ग अपने आप में एक वर्ग है? क्या यह कारण है कि सभी वस्तुएं "वर्ग" से संबंधित हैं? अवधारणा फ़र्ज़ी है , लेकिन मेरा मानना ​​है कि इसका कुछ करना है कि मैं क्लास विधि को बिल्कुल भी क्यों परिभाषित करूँ ( class foo; def foo.bar ...)।

रूबी में एकल वर्ग क्या है?

जवाबों:


154

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

irb(main):001:0> class Foo; def method1; puts 1; end; end
=> nil
irb(main):002:0> foo = Foo.new
=> #<Foo:0xb79fa724>
irb(main):003:0> def foo.method2; puts 2; end
=> nil
irb(main):004:0> foo.method1
1
=> nil
irb(main):005:0> foo.method2
2
=> nil
irb(main):006:0> other_foo = Foo.new
=> #<Foo:0xb79f0ef4>
irb(main):007:0> other_foo.method1
1
=> nil
irb(main):008:0> other_foo.method2
NoMethodError: undefined method `method2' for #<Foo:0xb79f0ef4>
        from (irb):8

उदाहरण विधियाँ एक वर्ग की विधियाँ हैं (अर्थात कक्षा की परिभाषा में परिभाषित)। कक्षा विधियाँ एकल वर्ग के Classउदाहरण पर एकल विधि हैं - वे वर्ग की परिभाषा में परिभाषित नहीं हैं। इसके बजाय, उन्हें ऑब्जेक्ट के सिंगलटन वर्ग पर परिभाषित किया गया है ।

irb(main):009:0> Foo.method_defined? :method1
=> true
irb(main):010:0> Foo.method_defined? :method2
=> false

आप सिंटैक्स के साथ किसी ऑब्जेक्ट का सिंगलटन वर्ग खोलें class << obj। यहाँ, हम देखते हैं कि यह सिंगलटन क्लास वह है जहाँ सिंगलटन विधियों को परिभाषित किया गया है:

irb(main):012:0> singleton_class = ( class << foo; self; end )
=> #<Class:#<Foo:0xb79fa724>>
irb(main):013:0> singleton_class.method_defined? :method1
=> true
irb(main):014:0> singleton_class.method_defined? :method2
=> true
irb(main):015:0> other_singleton_class = ( class << other_foo; self; end )
=> #<Class:#<Foo:0xb79f0ef4>>
irb(main):016:0> other_singleton_class.method_defined? :method1
=> true
irb(main):017:0> other_singleton_class.method_defined? :method2
=> false

तो एक ऑब्जेक्ट में सिंगलटन विधियों को जोड़ने का एक वैकल्पिक साधन उन्हें ऑब्जेक्ट के सिंगलटन क्लास ओपन के साथ परिभाषित करना होगा:

irb(main):018:0> class << foo; def method3; puts 3; end; end
=> nil
irb(main):019:0> foo.method3
3
=> nil
irb(main):022:0> Foo.method_defined? :method3
=> false

संक्षेप में:

  • विधियाँ हमेशा एक वर्ग की होनी चाहिए (या: किसी वर्ग की उदाहरण विधियाँ हों)
  • सामान्य विधियाँ उस वर्ग से संबंधित होती हैं जिसे वे परिभाषित करते हैं (अर्थात वर्ग की विधियाँ हैं)
  • क्लास के तरीके सिर्फ एक के सिंगलटन तरीके हैं Class
  • किसी ऑब्जेक्ट के सिंगलटन तरीके ऑब्जेक्ट के वर्ग के उदाहरण के तरीके नहीं हैं; बल्कि, वे वस्तु के एकल वर्ग के उदाहरण तरीके हैं।

17
मेरे हेडस्टोन पर यह कहेंगे "आरआईपी रूबी सिंगलटन। पिस्टोस ने मेरी पवित्रता को बचाया।"
१41

1
@ सावा मैं आपके संपादन के इरादे की सराहना करता हूं, लेकिन मुझे लगता है कि वे मेरे पोस्ट के अर्थ और संचार को थोड़ा बहुत बदल देते हैं, इसलिए मैंने आपके संपादन वापस ले लिए हैं।
पिस्तोस

33

रूबी उन तरीकों को परिभाषित करने का एक तरीका प्रदान करता है जो किसी विशेष वस्तु के लिए विशिष्ट होते हैं और ऐसे तरीकों को सिंगलटन मैथड्स के रूप में जाना जाता है। जब कोई ऑब्जेक्ट पर एक सिंगलटन विधि घोषित करता है, रूबी स्वचालित रूप से सिर्फ सिंगलटन विधियों को रखने के लिए एक वर्ग बनाता है। नव निर्मित वर्ग को सिंगलटन क्लास कहा जाता है।


    foo = Array.new
    def foo.size
      "Hello World!"
    end
    foo.size  # => "Hello World!"
    foo.class # => Array
    #Create another instance of Array Class and call size method on it
    bar = Array.new
    bar.size  # => 0
सिंगलटन क्लास ऑब्जेक्ट विशिष्ट अनाम वर्ग है जो स्वचालित रूप से बनाया जाता है और वंशानुक्रम पदानुक्रम में डाला जाता है।

singleton_methods एक ऑब्जेक्ट पर सभी सिंगलटन विधियों के लिए नामों की सूची प्राप्त करने के लिए किसी ऑब्जेक्ट पर कॉल किया जा सकता है।

    foo.singleton_methods  # => [:size]
    bar.singleton_methods  # => []

इस लेख ने मुझे रूबी में सिंगलटन क्लासेस को समझने में मदद की और इसका एक अच्छा कोड उदाहरण है।


4
यद्यपि यह उत्तर एक वर्ष से अधिक पुराना है और लिंक मददगार है, तो बेहतर होगा कि आप इस साइट पर उत्तर के आवश्यक भागों को पोस्ट करें, या आपकी पोस्ट के जोखिमों को हटाया जा रहा है FAQ देखें जहां यह उन उत्तरों का उल्लेख करता है जो 'बमुश्किल अधिक हैं' एक कड़ी से ’। यदि आप चाहें तो आप अभी भी लिंक को शामिल कर सकते हैं, लेकिन केवल 'संदर्भ' के रूप में। लिंक की आवश्यकता के बिना जवाब अपने दम पर खड़ा होना चाहिए।
टैरिन

यहां @bluefeet से सहमत हैं
सौरभ

धन्यवाद @bluefeet, ने आपकी टिप्पणी का जवाब देने के लिए अद्यतन किया।
बेदासो

7

जैसा कि @Pistos उत्तर में अपडेट किया गया है, संस्करण 1.9.2 माणिक से सिंगलटन वर्ग प्राप्त करने के लिए नया वाक्यविन्यास जोड़ें

 singleton_class = ( class << foo; self; end )

के साथ प्रतिस्थापित किया जा सकता है:

singleton_class = foo.singleton_class

https://apidock.com/ruby/Object/singleton_class


4

इसे (IMHO) सोचने का सबसे व्यावहारिक / एक्शन-ओविंटेड तरीका है: इनहेरिटेंस चेन, या मेथड लुकिंग / रिज़ॉल्यूशन ऑर्डर। यह चित्र मदद कर सकता है

http://www.klankboomklang.com/2007/11/25/modules-part-i-enter-the-include-class/

यह आर 1.9 है, बिल्टिन और उपयोगकर्ता-परिभाषित वर्गों के विपरीत है: मैं अभी भी इसे पचा रहा हूं।

http://d.hatena.ne.jp/sumim/20080111/p1

इसके अलावा, मैं एक भ्रमित प्रयोग शब्द "सिंगलटन ऑब्जेक्ट" है, जो अलग अवधारणा है। एक सिंगलटन ऑब्जेक्ट एक वर्ग से आता है जिसकी अपनी रचनाकार / इंस्टेंटिएटर विधि अधिक है ताकि आप उस वर्ग में से केवल एक को आवंटित कर सकें।


लिंक में से एक मर चुका है। और दूसरा जापानी है!
उलेसे बीएन

0

सबसे सरल शब्दों में एक सिंगलटन वर्ग एक विशेष वर्ग रूबी है जो व्यक्तिगत वस्तुओं पर परिभाषित तरीकों की मेजबानी करने के लिए सचेतक है। रूबी में, व्यक्तिगत वस्तुओं पर तरीकों को परिभाषित करना संभव है जो अकेले उस वस्तु के लिए अद्वितीय हैं। उदाहरण के लिए निम्नलिखित पर विचार करें

class User; end
user = User.new
def user.age
  "i'm a unique method"
end
user1 = User.new 
user.age #"i'm a unique method"
user1.age # NoMethodError (undefined method `age' for #<User:0x0000559c66ab7338>)

जैसा कि आप ऊपर देख सकते हैं, उपयोगकर्ता 1 ऑब्जेक्ट 'उम्र' पद्धति का जवाब नहीं देता है क्योंकि यह एक सिंगलटन विधि है, एक विधि विशिष्ट रूप से उपयोगकर्ता ऑब्जेक्ट पर परिभाषित की जाती है। ऐसा होने के लिए, रूबी एक विशेष वर्ग बनाता है, जिसे सिंगलटन क्लास, या ईजेनक्लस कहा जाता है, इस अनूठी पद्धति की मेजबानी करने के लिए। आप निम्न कार्य करके इसे सत्यापित कर सकते हैं:

user.singleton_class # #<Class:#<User:0x0000559c66b47c58>>

आप रूबी से यह भी पूछ सकते हैं कि क्या विधि 'ऑब्जेक्ट' का उपयोग करके यह पता लगाया जाता है कि विधि 'आयु' कहां है। जब आप ऐसा करेंगे तो आप देखेंगे कि सिंगलटन क्लास के पास वह तरीका है।

user_singleton_class = user.method(:age).owner # #<Class:#<User:0x0000559c66b47c58>>
user.method(:age).owner == user.singleton_class # true
user_singleton_class.instance_methods(false) # [:age]

यह भी ध्यान दें कि, जहाँ तक एक सिंगलटन वर्ग जाता है, सिंगलटन तरीके वास्तव में यह उदाहरण के तरीके हैं।

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