如何正确摧毁一个阶级
在Ruby中,我有一个DAO类,它通过一个类来扩展,这使得管理连接变得更容易,这个类由表示和操作DB中的数据的类扩展,该类由另一个类进一步扩展。 使用动物比喻它看起来像这样:
class Animal ... end class Mammal < Animal ... end class Feline < Mammal ... end class Cat < Feline ... end class Lion < Cat ... end ...
在PHP中,有一个__destruct
方法在您销毁/删除类时运行。 如果该类扩展另一个类,您只需将parent::__destruct()
到类的__destruct
方法中,如下所示:
public function __destruct() { // Clean up code for this class here ... // Execute clean up code for Parent class parent::__destruct(); }
我可以为除Animal
之外的所有类使用类似的方法。 由于它没有扩展任何东西,所以parent::__destruct();
行不再有效。
但是,据我所知,Ruby没有像这样的方法用于它的对象。 可以设置终结器,但我决定只是放入一个cleanup
方法,只要我想销毁/删除一个类,我就可以调用它。 在我将类设置为nil
之前,这将处理任何需要做的事情。
这引发了一个新问题。 如果该方法总是名为cleanup
并且我调用了lion_instance.cleanup
,我认为它调用了Lion#cleanup
。 然后如何让它在类Cat
然后在Feline
和链条上调用cleanup
?
或者这是一个错误的方法,你有一个更好的主意?
Ruby的习惯用法是生成一个可以正常工作的块,当块返回时,进行清理。 Ruby的内置“File.open”执行此操作:
File.open("/tmp/foo") do |file| file.puts "foo" end
当块结束时,文件将为您关闭,而您无需执行任何操作。 这是一个很好的习语。 以下是您可以实现类似的方法:
class Foo def self.open(*args) foo = new(*args) yield foo foo.close end def initialize # do setup here end def close # do teardown here end end
并使用它:
Foo.open do |foo| # use foo end
Foo#close
将在end
后自动生成
这也适用于子类化。 那是因为类方法和实例方法一样是inheritance的。 这是超类:
class Superclass def self.open(*args) o = new(*args) yield o o.close end def initialize # common setup behavior end def close # common cleanup behavior end end
和两个派生类:
class Foo < Superclass def initialize super # do subclass specific setup here end def close super # do subclass specific teardown here end end class Bar < Superclass def initialize super # do subclass specific setup here end def close super # do subclass specific teardown here end end
使用:
Foo.open do |foo| # use foo end Bar.open do |bar| # use bar end
如果你真的需要确保无论如何都要进行清理,那么在类方法中使用ensure子句:
def self.open(*args) foo = new(*args) begin yield foo ensure foo.close end end
这样,即使块中存在exception,也会发生清理。
您可以使用ObjectSpace.define_finalizer
就像是:
class Animal def initialize ObjectSpace.define_finalizer(self, proc { # your code }) end end
好吧,因为没有人回答你关于这个方法在inheritance链上移动的问题……
class Cat def rawr puts "rawr" end end class Kitty < Cat def rawr puts "meow" super end end Cat.new.rawr "Rawr" Kitty.new.rawr "rawr" "meow"
在方法中,您可以通过调用super来访问超类的同名方法。