spek icon indicating copy to clipboard operation
spek copied to clipboard

Make memoize call `close` if the instance was `Closeable`.

Open jcornaz opened this issue 6 years ago • 3 comments

Hi,

In our code-base we found useful to write the following helper:

fun <T : AutoCloseable> LifecycleAware.memoizedCloseable(mode: CachingMode = defaultCachingMode, factory: () -> T) =
    memoized(mode = mode, factory = factory, destructor = { it.close() })

The idea is that if we want to memorize something which implements Closeable, then chances are that we want to close it before forgetting its instance. And always passing a destructor is a bit boilerplate for our taste.

IMHO, it would be even better if memoized would close instances of AutoCloseable by default (eventually with an opt-out argument).

Because if something is closeable, then we will always want to close it right? And the fact that we have to do it manually, only increase the chances that we forget to do it.

jcornaz avatar Mar 28 '19 14:03 jcornaz

Is AutoCloseable available in the multiplatform stdlib? If yes, then we might be able to add it.

raniejade avatar Mar 28 '19 21:03 raniejade

Is AutoCloseable available in the multiplatform stdlib?

No :-(

However, I don't think it means that we cannot support it at all. There could be either:

  • A specific implementation of memoized only for the JVM
  • A specific extension function only for the JVM

It would be sad if the only reason to not add this is MPP support since there isn't any Spek runner for Javascript or Native at the moment. I understand it is a temporary situation, which will hopefully change as soon as Spek publish a runner for JavaScript and/or Native. But as of today, one should not use Spek to write multi-platform tests if he/she wants to actually run them on each platform.

jcornaz avatar Mar 29 '19 08:03 jcornaz

Makes sense, I think adding the following extension to the JVM is the way to go.

fun <T : AutoCloseable> LifecycleAware.memoizedCloseable(mode: CachingMode = defaultCachingMode, factory: () -> T) =
    memoized(mode = mode, factory = factory, destructor = { it.close() })

An alternative is let memoized handle it under the hood (using instanceof perhaps), but it's not very apparent.

raniejade avatar Mar 29 '19 22:03 raniejade