Issue #13923 has been updated by Eregon (Benoit Daloze).


IMHO this defer idea is not appropriate to manage resources at it just moves the release of the resources at the end of the method.
But this is often not appropriate or later than needed.
A block captures more explicitly the scope in which the resource is needed.
Moreover, if moving the release of the resource is needed, moving the closing }/end of the block is enough and much simpler than creating a new method to use defer for a shorter scope.
It is generally unwise to hold resources longer than necessary, particularly locks.

Taking the original example, and using blocks:

~~~ ruby
begin
  getStorage() do |storage|
    storage.get(buffer_id) do |buffer|
      # ...
    end
  end
rescue StorageError => e
  # ...
end
~~~

This naturally prevents using the resource after #close and clearly delimits when the resource is available.

----------------------------------------
Feature #13923: Idiom to release resources safely, with less indentations
https://bugs.ruby-lang.org/issues/13923#change-66856

* Author: tagomoris (Satoshi TAGOMORI)
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: 
----------------------------------------
In programs which grabs and releases resources very often, we need to write so much begin-ensure clauses.

```ruby
begin
  storage = getStorage()
  begin
    buffer = storage.get(buffer_id)

    # ...
  ensure
    buffer.close if buffer
  end
rescue StorageError => e
  # ...
ensure
  storage.close if storage
end
```

Such code makes our code fat, and difficult to understand.
I want to write such code like below:

```ruby
# Class of storage and buffer should include a module (like Closeable)
# or be checked with respond_to?(:close)

begin(storage = getStorage(); buffer = storage.get(buffer_id)
  # ...
rescue StorageError => e
  # ...
end
# (buffer.close if buffer) rescue nil
# (storage.close if storage) rescue nil
```

Other languages also have similar features:

* Java: try-with-resources
* Python: with




-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>