如何正确摧毁一个阶级

在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来访问超类的同名方法。