2010-04-18 4 views
6

में एक इंस्टेंस चर सेट होने पर कैसे पता चलेगा रूबी में इंस्टेंस चर के सेटिंग को ओवरराइड करने का कोई तरीका है?रूबी

@foo = "bar" 

मुझे लगता है कि रोकना कर सकते हैं और कुछ करना (यह रिकॉर्ड या पुट की तरह, उदाहरण के लिए)

मुझे लगता है, मैं काम ओवरराइड करने के लिए कोशिश कर रहा हूँ:

कहते हैं कि मैं एक उदाहरण चर सेट करने देता है सभी प्रकार के लिए ऑपरेटर। क्या यह भी किया जा सकता है?

class Module 
    def attr_log_accessor(*symbols) 
    symbols.each { | symbol | 
     module_eval("def #{symbol}() @#{symbol}; end") 
     module_eval("def #{symbol}=(val) 
         @#{symbol} = val 
         puts \"#{symbol} has changed\" 
        end") 
    } 
    end 
end 

तब, जब मैं एक्सेसर को परिभाषित करने और यह निर्धारित करते हैं, मेरी कोड का निष्पादित:

class Test 
    attr_log_accessor :foo 

    def DoSomething 
    self.foo = "bar" 
    end 
end 

दुर्भाग्य से,

सबसे अच्छा मैं के साथ आए हैं, अब तक, यह है इसके लिए मुझे @foo = "bar" की बजाय self.foo = "bar" लिखने की आवश्यकता है।

कोई विचार?

+0

को वहाँ 'trace_var' (http://www.ruby-doc.org/core/classes/Kernel.html#M005937) बदलना होगा, लेकिन केवल वैश्विक युद्धों के लिए। –

+0

वहाँ भी प्रत्यक्ष मॉड्यूल है, जो संभव के रूप में इस के रूप में पास हो सकता है: http://www.oreillynet.com/ruby/blog/2006/01/ruby_design_patterns_observer.html हालांकि, getters/setters के बजाय का उपयोग कर पड़ सकता है सीधे उदाहरण चर (जो मूल रूप से आप इसे कैसे अब कर रहे हैं) –

उत्तर

3

नहीं, आप इसे सीधे नहीं कर सकते हैं। इसका सबसे अच्छा तरीका केवल गेटटर/सेटर विधियों के माध्यम से आवृत्ति चर का उपयोग करना होगा और उनको ओवरराइड करना होगा।

1

आप instance_variable_get, instance_variable_set और instance_variables के साथ गड़बड़ कर सकते हैं। इस Ruby's Metaprogramming Toolbox आलेख में और भी पाया जा सकता है।

यदि आप वर्णन कर सकते हैं कि आप ऐसा करने का प्रयास क्यों कर रहे हैं तो हम एक बेहतर विधि प्रदान करने में सक्षम हो सकते हैं।

def method_missing(name, *args) 
    attribute = name.to_s 
    if attribute =~ /=$/ 
    @attributes[attribute.chop] = args[0] 
    else 
    @attributes[attribute] 
    end 
end 

आप अपने गेटर/सेटर में प्रसंस्करण है, तो इस विधि जल्दी से फूला हुआ बन जाएगा:

+0

की स्थापना मैं यह करने के कोशिश कर रहा हूँ, क्योंकि वर्ग पर विशिष्ट गुणों के लिए, मैं जब गुणों को बदलने के अन्य वस्तुओं को सूचित करना चाहते। अधिक विशेष रूप से, यह नेट के साथ एकीकृत करने के लिए है। मैं Ironotuby का उपयोग कर रहा हूँ और INotifyPropertyChanged.PropertyChanged घटना पर फायरिंग घटनाओं का उपयोग कर रहा हूँ। attr_notifiable: foo, या कुछ और जब भी @foo सेट कर दिया जाता है, यह ईवेंट सक्रिय मैं के रूप में दर्ज करना पड़ा हुआ एक संपत्ति घोषित करने के लिए करना चाहते हैं। आखिरकार, self.foo काम करेगा, लेकिन अगर मैं जमीन के तल पर (स्थानीय var के लिए असाइनमेंट) में प्रवेश कर सकता हूं, तो यह मेरे लिए और भी उपयोगी होगा। –

0

आप इस का उपयोग कर method_missing()

उदाहरण कर सकते हैं।

अधिक जानकारी के लिए, OpenStruct स्रोत देखें। इसके अलावा, मैं Metaprogramming Ruby (पृष्ठ 52)

इसके अलावा इस कोड खींच लिया, ध्यान दें कि यह सब याद आ रही तरीकों पकड़ लेंगे। आप उसके बाद ही obj.[*]= रोकना चाहते हैं, आप @attributes[attribute]super