2017-01-08 3 views
6

मैं रूबी के लिए एक न्यूबी हूँ। मैं निष्पादन की वर्तमान पंक्ति की विधि युक्त क्लास ऑब्जेक्ट प्राप्त करने का एक तरीका ढूंढ रहा हूं। क्या यह वर्गनाम को हार्डकोड किए बिना संभव है?रूबी: क्या कक्षा निर्धारित करना संभव है कि मेरी रूबी विधि क्लासनाम को हार्डकोड किए बिना निष्पादित कर रही है?

# hardcoded example 
class A 
    def to_s 
    "I am a " + A.to_s # Class "A" is hardcoded here. Is there another way to reference the class A? 
    end 
end 

मैंने सोचा कि शायद self.class काम करेगा, लेकिन यह मुझे नहीं दिया मैं जब कक्षा subclassed है के लिए क्या देख रहा था।

# Following Outputs=> I am a Camel I am a Camel I am a Camel 
# but I want  => I am a Camel I am a Mammal I am a Animal 

class Animal 
    def to_s 
    "I am a " + self.class.to_s 
    end 
end 

class Mammal < Animal 
    def to_s 
    "I am a " + self.class.to_s + " " + super 
    end 
end 

class Camel < Mammal 
    def to_s 
    "I am a " + self.class.to_s + " " + super 
    end 
end 

puts Camel.new() 

तो, क्या कोई कीवर्ड, विधि या कुछ है जो युक्त कक्षा तक पहुंचने की अनुमति देता है?

उत्तर

3

इस

Class.nesting.first 

प्रयास करें यह आपको एक विधि को परिभाषित करने वाली कक्षा देता है।

class A 
    def example 
    { defining_class: Class.nesting.first, self_class: self.class } 
    end 
end 

class B < A 
end 

B.new.example 
# => {:defining_class=>A, :self_class=>B} 
+0

वास्तव में अच्छा, मैंने इसके बारे में नहीं सोचा था! ध्यान दें कि ओपी प्रस्तावित वाक्यविन्यास के लिए आपको 'class.nesting.first.name' की आवश्यकता होगी। इसके अलावा, ओपी ने एक टिप्पणी में लिखा कि वह मॉड्यूल नहीं चाहता था, इसलिए कुछ तर्क की आवश्यकता हो सकती है। वैसे भी मामूली नाइटपिक्स हैं: बधाई हो! –

+0

नेस्टिंग लेक्सिकल संदर्भ है, इसलिए यह हमेशा कक्षा पर परिभाषित विधि के लिए एक कक्षा होगी। (एक असंबंधित नोट पर, मुझे लगता है कि ओपी ने अपने लिंग को कभी भी "वे" सर्वनाम का सबसे अच्छा उपयोग नहीं किया।) – akuhn

+0

विधि प्रीपेड मॉड्यूल से भी हो सकती है, है ना? मैंने कभी भी 'वे' का उपयोग नहीं किया है। मैं अगली बार ओपी उपयोगकर्ता नाम का उपयोग करूंगा। –

5

आप Class#ancestors की आवश्यकता होगी:

Camel.ancestors 
#=> [Camel, Mammal, Animal, Object, Kernel, BasicObject] 

आप अधिक वर्गों मिल जाएगा की तुलना में आप परिभाषित है, तो आप Object में बंद करना होगा:

class Animal 
    def to_s 
    "I am a " + self.class.ancestors.take_while{|klass| klass != Object}.join(' and a ') 
    end 
end 

class Mammal < Animal 
end 

class Camel < Mammal 
end 

puts Animal.new 
# => I am a Animal 
puts Mammal.new 
# => I am a Mammal and a Animal 
puts Camel.new 
# => I am a Camel and a Mammal and a Animal 

ancestors मॉड्यूल या वर्ग हो सकता है , इसलिए यदि आप सिर्फ कक्षा चाहते हैं, आप उपयोग कर सकते हैं:

def to_s 
    "I am a " + self.class.ancestors.take_while{|klass| klass < Object}.join(' and a ') 
end 

तो, वहाँ कोई कीवर्ड, विधि या कुछ है कि युक्त वर्ग तक पहुँचने की अनुमति देता है?

मुझे कोई नहीं मिला। करने के लिए Animal#to_s या Mammal#to_s अभी भी Camel रिटर्न

puts method(__method__).owner 

जोड़ा जा रहा है।

+0

कोड के लिए धन्यवाद। यह मेरे लिए सहायक है क्योंकि मैं रूबी में केवल 2 दिन हूं। हालांकि, मुझे लगता है कि आपने अभी उदाहरण कोड में सुधार किया है जिसका उपयोग मैंने यह दिखाने के लिए किया था कि "self.class" वह नहीं था जिसे मैं ढूंढ रहा था। साथ ही, मुझे लगता है कि अगर आपके कोड में शामिल किया गया तो आपके कोड में मॉड्यूल शामिल होंगे। उदाहरण के लिए "मैं एक ऊंट और कुछ मॉड्यूल हूं ...", और यह गलत होगा क्योंकि मॉड्यूल एक "है"/रचनात्मक संबंध है, न कि "एक है"। सही? लेकिन सभी बिंदु के बगल में है। जो जवाब मैं ढूंढ रहा हूं उसे मुझे केवल एक वर्ग वस्तु में ले जाना चाहिए, और इसे मेरे सभी उदाहरण वर्गों में "self.class" को प्रतिस्थापित करना चाहिए। – successhawk

+0

अब मैं आपका प्रश्न समझता हूं, लेकिन कुछ भी नहीं मिला। बीटीडब्ल्यू, आपकी समस्या '.class' नहीं है, लेकिन 'स्वयं' है। यह 'पशु' के लिए परिभाषित विधि में भी एक ही ऊंट वस्तु रहता है। –

+0

वहाँ है, 'class.nesting.first' – akuhn

संबंधित मुद्दे

 संबंधित मुद्दे