2016-09-15 14 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 

a_method ocassionally ném AException.Thêm cứu hộ trong mỗi phương thức trong một lớp

Tôi muốn giải cứu từ ngoại lệ đó, như:

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

    # ... 
end 

Tôi muốn cứu cách giống nhau trong mỗi phương pháp bên trong lớp B (method_1, method_2 ..., method_n). Tôi đang mắc kẹt trên việc tìm ra một giải pháp tốt đẹp và sạch sẽ, mà sẽ không yêu cầu phải nhân đôi khối mã cứu hộ. Bạn có thể giúp tôi với đó?

+0

BTW, "phương pháp lớp" có chút sai lệch. Đó là một thuật ngữ để phân biệt giữa _class methods_ và _instance methods_. – Stefan

+0

Đúng, tôi đã chỉnh sửa nó thành "từng phương thức bên trong lớp B" để loại bỏ vấn đề đó. – maicher

+0

Nếu bạn muốn chính xác mã số cứu hộ mỗi khi nó được gọi, tại sao không giải cứu trong lớp A? – Max

Trả lời

6

Làm thế nào về sử dụng một khối:

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

Tôi đã chọn giải pháp này. Tôi thấy nó rõ ràng nhất để sử dụng trong mã mà tôi làm việc. Cám ơn. – maicher

5

Như thế này, có lẽ?

class B < A 

    def method_1 
    # ... 
    safe_a_method 
    end 

    private 

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

Nếu bạn muốn luôn luôn giải cứu các ngoại lệ, bạn chỉ có thể ghi đè lên a_method trong B:

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

    # ... 
end 

Bên cạnh đó bạn có thể muốn trả về một giá trị (như nil hoặc false) để chỉ ra sự thất bại .

1

Bạn có thể quấn phương pháp bạn sử dụng một mô-đun như thế này. Lợi ích là không giống như các giải pháp khác, bạn có thể gọi các phương pháp của bạn với tên thông thường của chúng và bản thân các phương thức không cần phải thay đổi. Chỉ cần mở rộng lớp với phương pháp ErrorHandler vi ở cuối liệt kê các phương thức để bọc chúng với logic lỗi của bạn.

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 
Các vấn đề liên quan