Blair Zajac | 8 Feb 17:06
Gravatar

Adding ARM to Scala's standard library

Probably anybody that has written something that needs to be closed after use 
has written something like

object With
{
   def closeable[C <: java.io.Closeable,R](c: C)
                                          (f: C => R): R =
   {
     try {
       f(c)
     }
     finally {
       try {
        c.close()
       }
       catch {
         // #### Log this, but how?
         case e =>
       }
     }
   }
}

Then it would be used as

With.closeable(new ByteArrayOutputStream(1024)) { os =>
   ...
}

This looks like something that would do well in Scala's standard library.

One question is how to deal with the logger for the standard library.  I use 
slf4j in my projects but not everybody does.  I think if this code is in the 
standard library then it must provide a way to have the exception from #close() 
be logged with the logger of choice.  The With object could become an abstract 
class with an abstract logging method than projects would instantiate their own 
concrete class with their logger of choice.

abstract class With
{
   protected def logCloseException(t: Throwable): Unit
}

object MyWith
   extends With
{
   override protected def logCloseException(t: Throwable): Unit = ...
}

BTW, the reason not to use structural subtyping is performance and it doesn't 
work with Oracle's java.sql.ResultSet subclass:

   def with_closeable[T <: { def close(): Unit }]

   java.lang.IllegalAccessException: Class DatabaseCopy$ can not
   access a member of class oracle.jdbc.driver.OracleResultSetImpl
   with modifiers "public synchronized"
   at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:65)
   at java.lang.reflect.Method.invoke(Method.java:588)

Blair


Gmane