परीक्षण करें कि क्या रूबी वर्ग किसी अन्य वर्ग का उपवर्ग है


187

मैं परीक्षण करना चाहूंगा कि क्या एक वर्ग दूसरे वर्ग से विरासत में मिला है, लेकिन उसके लिए कोई विधि मौजूद नहीं है।

class A
end

class B < A
end

B.is_a? A 
=> false

B.superclass == A
=> true

जो मैं चाहता हूं उसका एक तुच्छ कार्यान्वयन:

class Class
  def is_subclass_of?(clazz)
    return true if superclass == clazz
    return false if self == Object
    superclass.is_subclass_of?(clazz)
  end
end

लेकिन मैं उम्मीद करूंगा कि यह पहले से ही मौजूद है।


2
A.class #=> Class। इसी कारण B.is_a? Aअसत्य लौटता है।
वेन

के बारे में क्याkind_of?
akostadinov

1
kind_of?परीक्षण करता है कि क्या एक वस्तु एक वर्ग का एक उदाहरण है। यह नहीं कि वस्तु एक वर्ग से विरासत में मिली है या नहीं।
कंफ्यूजन

5
kind_of?का एक उपनाम हैis_a?
Coreyward

जवाबों:


355

बस <ऑपरेटर का उपयोग करें

B < A # => true
A < A # => false

या <=ऑपरेटर का उपयोग करें

B <= A # => true
A <= A # => true

13
@Brian क्योंकि is_a?अनुवाद है का उदाहरण है । हालांकि , इसका Bउदाहरण नहीं है ( )। AB.newB.new.is_a? A # => true
मार्सेल जैकवर्थ

4
हम्म, अजीब वाक्यविन्यास (मेरा पहला अनुमान नहीं होगा), लेकिन स्पष्टीकरण के लिए धन्यवाद!
ब्रायन आर्मस्ट्रांग

2
दस्तावेज़ीकरण के लिए कोर एपीआई / मॉड्यूल / # <देखें
webwurst

2
रूबी के साथ मेरा प्रेम / घृणा का संबंध जारी है ... वर्ग संबंधों की घोषणा के लिए उपयोग किए जाने वाले ऑपरेटर के लिए एक अलग फ़ंक्शन प्रदान करें और इसे करने के दो अलग-अलग तरीके प्रदान करें?
बेन गोटोव

4
@BenGotow - 1. क्योंकि <एक ऑपरेटर नहीं है, यह एक विधि है। 2. क्योंकि <केवल एक उपवर्ग के लिए जाँच करता है, और <= भी स्वयं को शामिल करता है।
superluminary

59

भी उपलब्ध:

B.ancestors.include? A

यह (छोटा) के उत्तर से थोड़ा अलग है B < Aक्योंकि Bइसमें शामिल है B.ancestors:

B.ancestors
#=> [B, A, Object, Kernel, BasicObject]

B < B
#=> false

B.ancestors.include? B
#=> true

यह वांछनीय है या नहीं यह आपके उपयोग के मामले पर निर्भर करता है।


24
अधिक पठनीय: B <= B(समान परिणाम B.ancestors.include? B)।
मार्सेल Jackwerth

अपडेट: तुरंत पूर्ववर्ती समाधान 1.9+ के साथ काम करता है जबकि कोई "पूर्वज नहीं है?" 1.9 में।

8
यह लोगों को भ्रमित नहीं करेगा जो '<' वाक्यविन्यास से परिचित नहीं है, और इसी कारण से मैं इसे पसंद करता हूं।
असफंद क़ाज़ी

2
@SimonLepkin शायद "थोड़ी देर" नहीं है, जब तक आप माइक्रोसेकंड द्वारा टिक का अनुभव नहीं कर सकते। ;) हाँ, पूर्वजों की श्रृंखला के माध्यम से दृश्यों include?और <विधियों के पीछे । यह सी में ऐसा करता है, तो निश्चित रूप से रूबी सरणी के माध्यम से लूपिंग की तुलना में तेज है ... लेकिन व्यावहारिक रूप से दोनों को अप्रभेद्य होना चाहिए।
मेंढक

1
@JunanChakma अंग्रेजी शब्द "पूर्वजों" को कैसे परिभाषित किया गया है, इसके आधार पर, मैं मानता हूं कि वापसी मूल्य शामिल नहीं होना चाहिए B। लेकिन यह करता है। विधि दस्तावेज़ कहते हैं, "रिटर्न मॉड्यूल की एक सूची शामिल / (आधुनिक में prepended ही आधुनिक सहित )।" (जोर मेरा)। मैं अनुमान लगा रहा हूं कि इसका उपयोग करते समय सुविधा के लिए अपनी कक्षा शामिल है .include?, लेकिन यह सिर्फ मेरी ओर से अटकलें हैं।
फ्रॉग्ज
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.