在Ruby中,我有一个DAO类,它通过一个类来扩展,这使得管理连接变得更容易,这个类由表示和操作数据库中的数据的类扩展,该类由另一个类进一步扩展。使用动物比喻它看起来像这样:
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
。然后如何让它在课程cleanup
中调用Cat
,然后调用Feline
并在链上调用?
或者这是一种错误的做法,你有更好的想法吗?
答案 0 :(得分:6)
这方面的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
{p> Foo#close
将在end
后自动生成
这也适用于子类化。那是因为类方法和实例方法一样是继承的。这是超类:
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
这样,即使块中存在异常,也会发生清理。
答案 1 :(得分:2)
您可以使用ObjectSpace.define_finalizer
类似的东西:
class Animal
def initialize
ObjectSpace.define_finalizer(self, proc { # your code })
end
end
答案 2 :(得分:1)
好吧,因为没有人回答你关于这个方法在继承链上移动的问题......
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来访问超类的同名方法。