Optional use of a finally clause with a using clause

In some cases, you need to perform additional cleanup that is not handled automatically by one of the closable, reentrant, or disposable types. To add arbitrary cleanup logic to the using clause, add a finally clause after the using clause. The Gosu using clause with the finally clause is similar to the try-with-resources statement of Java 1.7 but without a catch clause.

Important notes about the finally clause:

  • The body of the using clause always runs before the finally clause.
  • If exceptions occur that are not caught, Gosu still runs the finally clause.
  • Your finally clause can access objects created in the using clause, but all resources are already cleaned up by the time the finally clause begins. For example, closeable objects are already closed and disposable objects are already disposed.

For example, create a disposable class:

// Create a disposable class -- it implements IDisposable
class TestDispose implements IDisposable {

  var _open : boolean as OpenFlag

  construct(){
    print("LOG: Created my object!")
    _open = true
  }

  override function dispose() {
    print("LOG: Disposed of my object! Note that you must support multiple calls to dispose.")
    _open = false
  }
}

The following code creates a disposable object in a using clause, and throws an exception in the body of the using clause. Note that the finally clause still runs:

using (var d = new TestDispose()) {
  print("LOG: In the body of the 'using' statement.")
  print("value of d.OpenFlag = ${d.OpenFlag}")

  print(3 / 0) // THROW AN EXCEPTION (divide by zero)
}
finally {
  print("LOG: In the finally clause.")
  print("value of d.OpenFlag = ${d.OpenFlag}")
}
print("LOG: Outside the 'using' clause.")

This example prints:

LOG: Created my object!
LOG: In the body of the 'using' statement.
value of d.OpenFlag = true
LOG: Disposed of my object! Note that you must support multiple calls to dispose.
LOG: In the finally clause.
value of d.OpenFlag = false

java.lang.ArithmeticException: / by zero
[...]

Notice in the output:

  • The using clause automatically cleaned up the disposable resource.
  • The finally clause still runs.
  • The finally clause can access the resource, which is already disposed.