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
The a_method
ocassionally throws an AException.
a_method偶尔会抛出一个AException。
I want to rescue from that exception, like:
我想从那个例外中解救,比如:
class B < A
def method_1
# ...
a_method
rescue AException => e
p e.message
end
# ...
end
I want to rescue the same way in each methods inside class B (method_1
, method_2
, ..., method_n
). I'm stuck on figuring out a nice and clean solution, that would not require to duplicate the rescue code block. Can you help me with that?
我想在B类(method_1,method_2,...,method_n)中的每个方法中以相同的方式进行挽救。我坚持找出一个漂亮而干净的解决方案,不需要复制救援代码块。你能帮帮我吗?
4 个解决方案
#1
8
How about to use a block:
如何使用块:
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
#2
5
If you want to always rescue the exception, you could just override a_method
in B
:
如果你想总是挽救异常,你可以在B中覆盖a_method:
class B < A
def a_method
super
rescue AException => e
p e.message
end
# ...
end
In addition you might want to return a value (like nil
or false
) to indicate the failure.
此外,您可能希望返回一个值(如nil或false)来指示失败。
#3
5
Like this, perhaps?
也许这样吗?
class B < A
def method_1
# ...
safe_a_method
end
private
def safe_a_method
a_method
rescue AException => e
...
end
end
#4
1
You can wrap your methods using a Module like this. The benefit is that unlike the other solutions you can call your methods with their regular names and the methods themselves don't have to be changed. Just extend the class with the ErrorHandler method en at the end enumerate the methods to wrap them with your errorhandling logic.
您可以使用像这样的模块包装您的方法。好处是,与其他解决方案不同,您可以使用常规名称调用方法,并且不必更改方法本身。只需使用ErrorHandler方法扩展类,最后枚举方法,使用错误处理逻辑将它们包装起来。
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
#1
8
How about to use a block:
如何使用块:
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
#2
5
If you want to always rescue the exception, you could just override a_method
in B
:
如果你想总是挽救异常,你可以在B中覆盖a_method:
class B < A
def a_method
super
rescue AException => e
p e.message
end
# ...
end
In addition you might want to return a value (like nil
or false
) to indicate the failure.
此外,您可能希望返回一个值(如nil或false)来指示失败。
#3
5
Like this, perhaps?
也许这样吗?
class B < A
def method_1
# ...
safe_a_method
end
private
def safe_a_method
a_method
rescue AException => e
...
end
end
#4
1
You can wrap your methods using a Module like this. The benefit is that unlike the other solutions you can call your methods with their regular names and the methods themselves don't have to be changed. Just extend the class with the ErrorHandler method en at the end enumerate the methods to wrap them with your errorhandling logic.
您可以使用像这样的模块包装您的方法。好处是,与其他解决方案不同,您可以使用常规名称调用方法,并且不必更改方法本身。只需使用ErrorHandler方法扩展类,最后枚举方法,使用错误处理逻辑将它们包装起来。
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