在 Ruby 中有什么方法可以基于繼承制定標準的救援策略嗎?
我想要一些類似的東西:
class Parent
def method
rescue StandardError => e
#handle error
end
end
class Child < Parent
def method
raise StandardError.new("ERROR") if error_present
#do some stuff
super
end
def error_present
#checks for errors
end
end
我期望的結果是,當StandardError在孩子的方法中提出時,它將從父母的方法定義中解救出來。
如果這是不可能的,有沒有其他方法可以實作這種行為?
uj5u.com熱心網友回復:
恐怕這是不可能的——一種方法rescue只能挽救其體內出現的錯誤。
解決這個問題的一種方法是提供另一種方法來覆寫子類:
class Parent
# This is the public interface of the class, it is not supposed to be overriden
def execute!
perform
rescue => e
# do_sth_with_error
end
private
# Private implementation detail, override at will
def perform
end
end
class Child < Parent
private
def perform
raise "Something" if something?
# do some more things
super
end
end
Child.new.execute!
話雖如此-請不要救援StandardError。它會讓你未來的除錯成為一場噩夢。而是創建您自己的錯誤子類。
uj5u.com熱心網友回復:
你可以有這樣的策略,但這取決于它應該如何作業以及你的代碼是如何組織的。這種模式可以擴展。對于您的特定情況,您可以按如下方式組織代碼:
class Parent
def my_method(arg1, arg2)
yield if block_given?
# some code that should be run by Parent#my_method
rescue StandardError => e
# handle the error
end
end
class Child < Parent
def my_method(arg1, arg2)
super do
# code that should be run by Child#my_method
raise StandardError.new('error message') if error?
# maybe more code that should be run by Child#my_method
end
end
def error?
true
end
end
使用此策略,您必須將子方法中的所有代碼作為塊通過呼叫傳遞給父方法,該super呼叫是唯一的陳述句(好吧,基本上它是在繼承鏈中傳遞的閉包)。當然,此策略假定您的方法不使用塊來實作其正常邏輯,并且您可以專門為此執行注入使用此功能。
如果您想使用此策略擁有兩個以上的繼承級別,則必須對每個下一個方法使用相同的技巧:
class C
def m1
yield if block_given?
# ...
rescue SomeError
# ...
end
end
class B < C
def m1
super do
yield if block_given?
# ...
end
end
end
class A < B
def m1
super do
raise SomeError if condition
# ...
end
end
end
if block_given?如果您應用此策略,很可能您可以洗掉這些部分。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/355025.html
