2009-06-11 14 views
5

मेरे पास जिज्ञासा प्रश्न है। अगर मेरे पास रूबी क्लास है और फिर मैं गतिशील रूप से कक्षा विधियों, कक्षा चर, इत्यादि को निष्पादन के दौरान जोड़ता हूं, वैसे भी मेरे लिए बदली गई कक्षा परिभाषा को सहेजने के लिए है ताकि अगली बार जब मैं अपना आवेदन शुरू करूं तो मैं इसे फिर से उपयोग कर सकता हूं?सेविंग डायनामिक रूबी क्लासेस

उत्तर

1

बस ऑब्जेक्ट को मार्शल करना (जैसा कि अन्य ने कहा है) काम नहीं करेगा। चलिए एक उदाहरण देखें। इस वर्ग पर विचार करें:

class Extras 
    attr_accessor :contents 
    def test 
    puts "This instance of Extras is OK. Contents is: " + @contents.to_s 
    end 

    def add_method(name) 
    self.class.send :define_method, name.to_sym do 
     puts "Called " + name.to_s 
    end 
    end 
end 

अब एक प्रोग्राम है जो एक उदाहरण बनाता है, लिखने की सुविधा देता है इसे करने के लिए एक विधि कहते हैं और डिस्क के लिए यह बचाता है:

require 'extras' 

fresh = Extras.new 
fresh.contents = 314 
fresh.test # outputs "This instance of Extras is OK. Contents is: 314" 
fresh.add_method(:foo) 
fresh.foo # outputs "Called foo" 

serial = Marshal.dump(fresh) 
file = File.new "dumpedExample", 'w' 
file.write serial 

तो हम सामान्य विधि कॉल कर सकते हैं 'परीक्षण' और गतिशील विधि 'foo'। क्या होता है अगर हम एक प्रोग्राम है जो उदाहरण के उदाहरण है, जिसमें डिस्क पर सहेजा गया था लोड करता है लिखने को देखने की सुविधा देता है:

require 'extras' 

file = File.new 'dumpedExample', 'r' 
serial = file.read 

reheated = Marshal.load(serial) 
reheated.test # outputs "This instance of Extras is OK. Contents is 314" 
reheated.foo # throws a NoMethodError exception 

तो हम देख सकते हैं कि जब उदाहरण (सदस्य चरों के मान सहित) गतिशील विधि बचा लिया गया था नहीं था।

एक डिज़ाइन बिंदु से, संभवतः आपके सभी जोड़े गए कोड को मॉड्यूल में रखना बेहतर है और जब आप प्रोग्राम को अगली बार चलाते हैं तो कक्षा में फिर से लोड करना बेहतर होता है। हमें वास्तव में यह जानने के लिए कि आप इसका उपयोग कैसे करना चाहते हैं, इसका एक अच्छा उदाहरण चाहिए।

यदि आपको विधियों को फिर से बनाने के लिए अतिरिक्त जानकारी की आवश्यकता है तो मॉड्यूल को सदस्य चर के रूप में सहेजें। मॉड्यूल में included लागू करें और इसे कक्षा में शामिल होने पर इन सदस्य चर के लिए देखें।

-1

आप फ्लाई पर कक्षा संपादित कर रहे हैं, और आप इसे सहेजना चाहते हैं? आप मार्शल मॉड्यूल का उपयोग करने का प्रयास कर सकते हैं, यह आपको ऑब्जेक्ट्स को फाइल में सहेजने की अनुमति देगा, और उन्हें स्मृति में गतिशील रूप से वापस पढ़ेगा।

4

कोई अंतर्निहित तरीका यह है नहीं है। मार्शल विधियों को बचा नहीं सकता है। यदि कुछ व्यवस्थित तरीके से इन विधियों और चर उत्पन्न होते हैं, तो आप वर्ग को पुन: बनाने के लिए आवश्यक डेटा को सहेज सकते हैं। उदाहरण के लिए, यदि आपके पास make_special_method(purpose, value) विधि है जो इन विधियों को परिभाषित करती है, तो इन विधियों को पारित करने के लिए आपको आवश्यक तर्कों की एक सरणी बनाएं और जब आप कक्षा की स्थिति का पुनर्गठन करना चाहते हैं तो इसे पढ़ें।

2

इस बात के आधार पर कि आप वास्तव में क्या मतलब रखते हैं, इसके बारे में कुछ तरीके हैं।

सबसे सामान्य स्थिति एक है जहाँ आप एक पहले से ही मौजूदा वर्ग के लिए चर या विधियां जोड़ दी हैं इस उदाहरण में, यह है:

class String 
    def rot13 
    return self.tr('a-z', 'n-za-m') 
    end 
end 

यहाँ हम वर्ग स्ट्रिंग के लिए ROT13 विधि जोड़ दिया है। जैसे ही यह कोड चलाया जाता है, आपके प्रोग्राम में हर जगह हर स्ट्रिंग # rot13 में सक्षम हो जाएगी। इस प्रकार, यदि आपके पास कुछ कोड है जो rot13- सक्षम तारों की आवश्यकता है, तो आप बस सुनिश्चित करें कि उपरोक्त कोड प्रश्न में कोड से पहले चलाया गया है, उदा। रोट 13 कोड को किसी फ़ाइल में किसी स्थान पर डालकर और इसे() करने की आवश्यकता होती है। बहुत आसान!

लेकिन हो सकता है आप एक वर्ग के लिए एक वर्ग चर जोड़ दिया है, और आप ही नहीं, अपने अस्तित्व लेकिन अपने मूल्य को संरक्षित करने में के रूप में चाहते हैं:

class String 
    @@number_of_tr_calls_made = 0 
    # Fix up #tr so that it increments @@number_of_tr_calls_made 
end 

अब अगर आप का मान सहेजना चाहते @ @number_of_tr_calls_made, आप मार्शल लाइब्रेरी के माध्यम से किसी भी अन्य धारावाहिक रूबी मान के साथ ऐसा ही कर सकते हैं। भी आसान है!

लेकिन जिस तरह से आप अपने प्रश्न phrased में कुछ मुझे बनाता संदेह है कि आप कुछ इस तरह कर रहे हैं:

greeting = "Hello" 
class <<greeting 
    def rot13 
    return self.tr('a-z', 'n-za-m') 
    end 
end 
encrypted_greeting = greeting.rot13 

इसी को हम पहले उदाहरण में किया था से बहुत अलग है। कोड के उस टुकड़े ने आपके प्रोग्राम में प्रत्येक स्ट्रिंग को अपने आप को रोट 13 करने की शक्ति दी। यह कोड उस शक्ति को केवल 'ग्रीटिंग' नाम से संदर्भित वस्तु को अनुदान देता है। आंतरिक रूप से, रूबी स्ट्रिंग के एक अनाम सिंगलटन सबक्लास बनाकर ऐसा करता है, इसमें rot13 विधि जोड़ता है, और उस अज्ञात उप-वर्ग में ग्रीटिंग की कक्षा बदल रहा है।

समस्या यह है कि सिंगलेट्स को मार्शल नहीं किया जा सकता है (यह देखने के लिए कि क्यों मार्शल.लोड को किसी भी कॉल को मौजूदा सिंगलटन ऑब्जेक्ट्स की प्रतियां उत्पन्न कर सकते हैं) सिंगलटन इनवेरिएंट को बनाए रखने का तरीका जानने का प्रयास करें। अब अभिवादन में सिंगलटन की विरासत पदानुक्रम है, इसलिए यदि आप इसे सहेजना और लोड करना चाहते हैं तो आप को रोक दिया गया है। इसके बजाय उप-वर्ग बनाएं:

class HighlySecurableString < String 
    def rot13 
    return self.tr('a-z', 'n-za-m') 
    end 
end 
greeting = HighlySecurableString.new("hello") 
+0

मुझे लगता है कि पूछताछ निष्पादन के दौरान कक्षा में जोड़े गए तरीकों का जिक्र कर रहा था। अर्थात। metaprogrammed तरीकों। मैंने गलत समझा होगा। – toholio

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