2016-09-15 11 views
5
class A 
    def a_method 
    #.. 
    end 
end 

class B < A 
    def method_1 
    # ... 
    a_method 
    end 

    def method_2 
    # ... 
    a_method 
    end 

    # ... 

    def method_n 
    # ... 
    a_method 
    end 
end 

ocassionally एक अपवाद को फेंक देता है।कक्षा

मैं की तरह, कि अपवाद से बचाने के लिए करना चाहते हैं:

class B < A 
    def method_1 
    # ... 
    a_method 
    rescue AException => e 
    p e.message 
    end 

    # ... 
end 

मैं कक्षा बी के अंदर प्रत्येक तरीकों में एक ही तरह से बचाने के लिए चाहते हैं (method_1, method_2, ..., method_n)। मैं एक अच्छा और साफ समाधान लगाने के लिए फंस गया हूं, जिसे बचाव कोड ब्लॉक को डुप्लिकेट करने की आवश्यकता नहीं होगी। क्या उसके लिए आपके द्वारा मेरी मदद की जाएगी?

+0

बीटीडब्ल्यू, "कक्षा विधि" थोड़ा भ्रामक है। यह _class विधियों_ और _instance विधियों_ के बीच अंतर करने का एक शब्द है। – Stefan

+0

सच है, मैंने इसे उस समस्या को खत्म करने के लिए "कक्षा बी के अंदर प्रत्येक विधियों" में संपादित किया है। – maicher

+0

यदि आप हर बार सही बचाव कोड चाहते हैं, तो उसे ए क्लास में क्यों नहीं बचाया जाए? – Max

उत्तर

6

कैसे के बारे में एक ब्लॉक का उपयोग करें:

class B < A 
    def method_1 
    # some code here which do not raised an exception 
    with_rescue do 
     # method which raised exception 
     a_method 
    end 
    end 

    def method_2 
    with_rescue do 
     # ... 
     a_method 
    end 
    end 

    private 

    def with_rescue 
    yield 
    rescue => e 
    ... 
    end 
end 
+0

मैंने इस समाधान को चुना है। मैंने इसे उस कोड में उपयोग करने के लिए सबसे स्पष्ट पाया है जिस पर मैं काम करता हूं। धन्यवाद। – maicher

5

इस तरह, शायद?

class B < A 

    def method_1 
    # ... 
    safe_a_method 
    end 

    private 

    def safe_a_method 
    a_method 
    rescue AException => e 
    ... 
    end 
end 
5

आप हमेशा अपवाद को बचाने के लिए चाहते हैं, तो आप सिर्फ रद्द कर सकते थे B में a_method:

class B < A 
    def a_method 
    super 
    rescue AException => e 
    p e.message 
    end 

    # ... 
end 

इसके अलावा आप एक मूल्य (जैसे nil या false) विफलता का संकेत करने के लिए वापस जाने के लिए चाहते हो सकता है ।

1

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

module ErrorHandler 
    def wrap(method) 
    old = "_#{method}".to_sym 
    alias_method old, method 
    define_method method do |*args| 
     begin 
     send(old, *args) 
     rescue => e 
     puts "ERROR FROM ERRORHANDLER #{e.message}" 
     end 
    end 
    end 
end 

class A 
    extend ErrorHandler 
    def a_method v 
    "a_method gives #{v.length}" 
    end 
    (self.instance_methods - Object.methods).each {|method| wrap method} 
end 

class B < A 
    extend ErrorHandler 
    def method_1 v 
    "method_1 gives #{v.length}" 
    end 
    (self.instance_methods - Object.methods).each {|method| wrap method} 
end 

puts A.new.a_method "aa" # a_method gives 2 
puts A.new.a_method 1 # ERROR FROM ERRORHANDLER undefined method `length' for 1:Fixnum 
puts B.new.method_1 1 # ERROR FROM ERRORHANDLER undefined method `length' for 1:Fixnum