2011-06-01 4 views
9

मैं रूबी में कुछ metaprogramming कर रहा हूँ, और मैं गतिशील रूप से एक मॉड्यूल के अंदर एक भाई वर्ग उत्पन्न करने के लिए की जरूरत है। ऐसा करने में, मैं मॉड्यूल पर const_set को कॉल करना चाहता हूं, लेकिन मुझे नहीं पता कि कौन सा मॉड्यूल निरंतर रनटाइम तक कॉल करता है। एक उदाहरण: जब बुलारूबी: कक्षा के संलग्न मॉड्यूल कॉन्स को पाने का कोई तरीका है?

def generate_from klass 
    mod = klass.enclosing_module # <- THIS LINE is the one I need to figure out 
    mod.const_set("GeneratedClassName", Class.new) 
end 

और क्या मैं, के साथ खत्म करना चाहते हैं:

को देखते हुए वर्गों

Foo::Bar::Baz 
Foo::Quox::Quack 

मैं इस तरह एक समारोह (यहाँ oversimplified) कॉल करने के लिए सक्षम होना चाहते हैं Baz साथ, एक नया वर्ग के रूप में

Foo::Bar::GeneratedClassName 

और एक नीम हकीम के साथ परिभाषित किया गया है, मैं चाहता हूँ

Foo::Quox::GeneratedClassName 

एक ही रास्ता मैं जानता हूँ कि की klass.name को विभाजित करने के लिए, तो बार-बार उन तारों पर const_get फोन, constantized है। क्या किसी को और अधिक सुरुचिपूर्ण तरीके से पता है?

+0

केवल दो तरीके मैं कर जिस तरह से आप तल पर वर्णन किया जाएगा के बारे में पता था और इसमें प्रत्येक वर्ग में 'get_module' फ़ंक्शन। लेकिन, ऐसा लगता है कि * ऐसा करने का एक तरीका होना चाहिए। इस पर नजर रखने ... – drharris

उत्तर

7

समझ गया। ActiveSupport में यह रूबी एक्सटेंशन, मॉड्यूल # मूल है। यह मेरे उपयोग के लिए काफी अच्छा है।

+1

मैं एक और तरीका है कि आप मामले में मदद मिल सकती है कि आप इस के लिए ही ActiveSupport का उपयोग नहीं करना चाहते हैं पाया। यदि आप किसी भी तरह रेल का उपयोग कर रहे हैं, तो यह कोई चिंता नहीं है। –

+0

मैं अपने जवाब को स्वीकार कर लिया है, क्योंकि यह किया था मैं ActiveSupport वास्तव में क्या मैं चाहता था और उपयोग कर रहा हूँ, लेकिन मैं माइकल के जवाब upvoted के बाद से यह भी सही लगता है जब ActiveSupport – Matt

+0

का उपयोग नहीं कर मत सोचो लिंक अब और काम कर रहा है>/ – Ingo

17

इस ट्रैक पर मिलना चाहिए:

module Foo 
    module Bar 
    class Baz 
     def initialize 
     @nesting = Module.nesting 
     end 

     def enclosing_module 
     @nesting.last 
     end 
    end 
    end 
end 

puts Foo::Bar::Baz.new.enclosing_module #=> Foo 

प्रासंगिक दस्तावेज:

http://ruby-doc.org/core/classes/Module.html#M000441

+1

यह नहीं करता है ' काम नहीं विरासत के साथ (या शायद अप्रत्याशित कुछ करता है) - यदि आप एक उपवर्ग 'Corge :: Qux <फू :: बार :: Baz', बनाने' Corge :: Qux.new.enclosing_module' अभी भी Foo' होगा '। –

+0

सच है। मैंने स्वीकार्य रूप से विरासत के साथ परीक्षण नहीं किया, यही कारण है कि मैंने कहा "आपको ट्रैक पर ले जाना चाहिए", न कि "आपको वही चाहिए"। हालांकि प्रतिक्रिया के लिए धन्यवाद! –