Issue #13923 has been updated by nobu (Nobuyoshi Nakada).


How about:

```ruby
class Deferred
  def initialize
    @list = []
    yield self
  ensure
    @list.reverse_each do |res, clean|
      clean.(res)
    end
  end
  def defer(res = true, &clean)
    @list << [res, clean||CLOSE] if res
    res
  end
  CLOSE = :close.to_proc
end

if $0 == __FILE__
  class Resource
    @@number = 0
    def initialize
      @num = @@number += 1
    end
    def close
      puts "#@num closed"
    end
    def delete
      puts "#@num deleted"
    end
  end

  Deferred.new do |d|
    r0 = Resource.new
    d.defer {r0&.close}

    r1 = Resource.new
    d.defer r1

    r2 = d.defer Resource.new
    abort unless Resource === r2

    r3 = d.defer(Resource.new) {|r|r.delete}
  end
end
```

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

* 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>