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


While `ensure` in ruby is a syntax and share the scope, `defer` in go dynamically registers the clean-up code with capturing local variables implicitly.
So a `defer` in a loop may registers multiple times with different objects, or may not register by a condition.

```go
package main

import (
    "fmt"
)

type foo struct {
    n int
}

func Create(n int) *foo {
    fmt.Printf("Creating %v\n", n)
    return &foo{n}
}

func Delete(f *foo) {
    fmt.Printf("Deleting %v\n", f.n)
}

func main() {
    fmt.Println("Start")
    for i := 1; i <= 3; i++ {
        f := Create(i)
        if i % 2 != 0 {
            defer Delete(f)
        }
    }
    fmt.Println("Done")
}
```
shows

```
$ go run test.go 
Start
Creating 1
Creating 2
Creating 3
Done
Deleting 3
Deleting 2
Deleting 1
```

I think that `Kernel#defer` in Kona's proposal would be possible, but it would be hard to capture local variables.

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

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