ruby - Ruby 中的 RAII(或者,如何在 Ruby 中管理资源)

标签 ruby resources destructor raii finalizer

我知道这是设计使然,您无法控制对象被销毁时发生的情况。我也知道将某些类方法定义为终结器。

但是 C++ RAII 的 ruby​​ 习语是什么(资源在构造函数中初始化,在析构函数中关闭)?即使发生错误或异常,人们如何管理对象内部使用的资源?

使用确保有效:

f = File.open("testfile")
begin
  # .. process
rescue
  # .. handle error
ensure
  f.close unless f.nil?
end

但是每次需要调用 open 方法时,该类的用户都必须记住执行整个 begin-rescue-ensure chacha

例如,我将有以下类(class):

class SomeResource
 def initialize(connection_string)
   @resource_handle = ...some mojo here...
 end

 def do_something()
   begin
    @resource_handle.do_that()
    ...
   rescue
    ...
   ensure
 end

 def close
  @resource_handle.close
 end

end

如果异常是由其他类引起的并且脚本退出,则不会关闭 resource_handle。

或者更多的问题是我还在做类似 C++ 的事情?

最佳答案

这样用户就不必“必须记住做整个 begin-rescue-ensure chacha”将 rescue/ensure产量

class SomeResource
  ...
  def SomeResource.use(*resource_args)
    # create resource
    resource = SomeResource.new(*resource_args) # pass args direct to constructor
    # export it
    yield resource
  rescue
    # known error processing
    ...
  ensure
    # close up when done even if unhandled exception thrown from block
    resource.close
  end
  ...
end

客户端代码可以如下使用它:

SomeResource.use(connection_string) do | resource |
  resource.do_something
  ... # whatever else
end
# after this point resource has been .close()d

事实上,这就是 File.open 的运作方式 - 充其量让第一个答案变得困惑(对我的同事来说)。

File.open("testfile") do |f|
  # .. process - may include throwing exceptions
end
# f is guaranteed closed after this point even if exceptions are 
# thrown during processing

关于ruby - Ruby 中的 RAII(或者,如何在 Ruby 中管理资源),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/214642/

相关文章:

ruby-on-rails - apache 上的 redmine 找不到 Rack

java - 尝试使用 OWASP ESAPI 时找不到 antisamy-esapi.xml

c++ - 可以使用类的析构函数内部函数来重置值吗?

c++ - C++ 析构函数中的堆栈溢出

ruby-on-rails - Rails4 : Why resque worker is not picking up jobs

Ruby 将打开文件但不写入文件?

ruby-on-rails - 在 ruby​​ 中一次移动所有具有相同扩展名的文件

c# - 基于文件的 ResourceManager 如何回退到嵌入式资源?

wpf - 样式或资源中的WPF DataGrid列

c++ - 通过 C++ 中的指针在对象之间共享数据