2012-01-06 42 views
9

एक मणि को देखते हुए जो मैंने लिखा है कि कुछ कोड के साथ संघर्ष करने वाले शीर्ष-स्तरीय वर्गों को परिभाषित करता है, क्या इस तरह के मणि की आवश्यकता होती है कि इसकी सभी कक्षाओं को मॉड्यूल के अंदर समूहीकृत किया जाए मैं परिभाषित कर सकता हूँ? उदाहरण के लिए, एक unsafe_gem एक वर्ग को परिभाषित करता है, तो:उपयोगकर्ता द्वारा परिभाषित नामस्थान में रूबी मणि लोड करें

class Word 
    # ... some code 
end 

मैं की तरह कुछ की आवश्यकता होगी:

class Word 
    # My word class. 
end 

module SafeContainer 
    # This obviously doesn't work 
    # (i.e. the gem still defines ::Word). 
    require 'unsafe_gem' 
end 

तो यह है कि मैं अलग कर सकते हैं के बीच:

Word.new # => The class I defined. 
SafeContainer::Word.new # => The class defined by the gem. 

कुछ अधिक जानकारी: मेरा कोड (उदाहरण के लिए 'वर्ड' क्लास) पहले से ही अपने नामस्थान में लपेटा गया है। हालांकि, मैं उपयोगकर्ता को "सिंटेक्टिक चीनी" के रूप में सक्षम करने के विकल्प के साथ प्रदान करने में सक्षम होना चाहता हूं, जो कुछ वर्गों को शीर्ष-स्तर के नामस्थान के नीचे सीधे पहुंच योग्य बनाता है। हालांकि, यह एक रत्न का उपयोग कर रहा है जिसमें से एक रत्न का उपयोग कर रहा हूं, जो एक शीर्ष-स्तरीय वर्ग को परिभाषित करता है। वर्तमान में प्रस्तावित समाधानों में से कोई भी काम नहीं करता है क्योंकि मणि वास्तव में इसकी वैश्विक स्तर पर परिभाषित कक्षा पर निर्भर करता है; इसलिए वर्ग को अपरिभाषित करने से मणि टूट जाता है। बेशक, मणि में एक से अधिक फाइलें हैं, और व्यक्तिगत रूप से मॉड्यूल में अपनी फाइलों की आवश्यकता होती है, यह बहुत ही भंगुर समाधान लगता है। वर्तमान में, केवल वैकल्पिक हल मैं पाया है यह है:

begin 
    # Require the faulty gem. 
    require 'rbtagger' 
rescue 
    # If syntactic sugar is enabled... 
    if NAT.edulcorated? 
    # Temporarily remove the sugar for the clashing class. 
    Object.const_unset(:Word); retry 
    else; raise; end 
ensure 
    # Restore syntactic sugar for the clashing class. 
    if NAT.edulcorated? 
    Object.const_set(:Word, NAT::Entities::Word) 
    end 
end 

मैं पता नहीं क्यों, लेकिन यह मेरे toenails कर्ल बनाता है। किसी के पास बेहतर समाधान है?

उत्तर

4

एक और, संभवतः बेहतर उत्तर, this प्रश्न से आता है। तथ्य की

लाभ उठाएं कि वर्गों और मॉड्यूल हैं सिर्फ वस्तुओं, इसलिए जैसे:

require 'unsafe_gem' 
namespaced_word = Word 
Word = nil 


# now we can use namespaced_word to refer to the Word class from 'unsafe_gem' 

#now your own code 
class Word 
    #awesome code 
end 

आप यह सुनिश्चित करें कि unsafe_gem केवल एक वर्ग को परिभाषित करता बनाने के लिए है, और है कि आप require यह इससे पहले कि आप अपने खुद के वर्गों को परिभाषित और मॉड्यूल ताकि आप गलती से अपनी खुद की सामग्री nil पर सेट न करें।

1

मुझे लगता है कि आपकी सबसे अच्छी शर्त मॉड्यूल में अपना कोड लपेटना है। आपके द्वारा लिखे गए कोड के आधार पर, यह एक बड़ा दर्द हो सकता है या नहीं भी हो सकता है। हालांकि, यह सुनिश्चित करने का सबसे अच्छा तरीका है कि आपका कोड किसी और के साथ संघर्ष नहीं करेगा।

तो अपने Word वर्ग

module LoismsProject 
    class Word 
    #some awesome code 
    end 
end 

इस तरह आप सुरक्षित रूप से require 'unsafe_gem' कर सकते हो जाता है।

0

सरल जवाब है "नहीं"

अगर हम एक फ़ाइल 'word.rb' है;

class Word 
    def say 
    puts "I'm a word" 
    end 
end 

और हम कोशिश करते हैं और यह require, यह हमेशा वैश्विक क्षेत्र में लोड होगा।

यदि आपको पता था कि मणि सिर्फ एक ही फाइल थी, तो आप निम्न कार्य कर सकते थे।

module SafeContainer 
    module_eval(File.read("word.rb")) 
end 

लेकिन यह आपके मामले में काम करने की संभावना है।

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