I know it's by design that you can't control what happens when an object is destroyed. I am also aware of defining some class method as a finalizer.
However is the ruby idiom for C++'s RAII (Resources are initialized in constructor, closed in destructor)? How do people manage resources used inside objects even when errors or exceptions happen?
Using ensure works:
f = File.open("testfile")
begin
# .. process
rescue
# .. handle error
ensure
f.close unless f.nil?
end
but users of the class have to remember to do the whole begin-rescue-ensure chacha everytime the open method needs to be called.
So for example, I'll have the following 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
The resource_handle won't be closed if the exception is cause by some other class and the script exits.
Or is the problem more of I'm still doing this too C++-like?
So that users don't "have to remember to do the whole begin-rescue-ensure chacha" combine rescue
/ensure
with yield
.
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
Client code can use it as follows:
SomeResource.use(connection_string) do | resource |
resource.do_something
... # whatever else
end
# after this point resource has been .close()d
In fact this is how File.open
operates - making the first answer confusing at best (well it was to my work colleagues).
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With