Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write a class destructor in Scala?

I'd like to have a FileWriter opened during the whole time a class instance exists. So I need to close it in a destructor. But how to specify a destructor in Scala?

like image 470
Ivan Avatar asked Oct 23 '10 03:10

Ivan


People also ask

How do I create a class constructor in Scala?

In Scala, we are allowed to make a primary constructor private by using a private keyword in between the class name and the constructor parameter-list.

How do you create a class in Scala?

In Scala, an object of a class is created using the new keyword. The syntax of creating object in Scala is: Syntax: var obj = new Dog();

Can Scala object have constructor?

Scala ConstructorThere are two types of constructor in Scala – Primary and Auxiliary. Not a special method, a constructor is different in Scala than in Java constructors. The class' body is the primary constructor and the parameter list follows the class name.


2 Answers

You might be interested to check out Josh Suereth's scala-arm project, which provides both monadic and delimited-continuation based resource management for just this source of use: http://github.com/jsuereth/scala-arm

If you really think that you need a destructor (i.e. because you think you need to create the object and then hand it off and never see it again) I'd recommend reconsidering your application architecture instead... there is simply no way to make this work reliably on the JVM.

like image 63
Kris Nuttycombe Avatar answered Sep 18 '22 16:09

Kris Nuttycombe


Here's a handy utility method I use frequently. I find that it unclutters my code nicely.

def closer [T, C <: Closeable] (c : C) (f : C => T) : T = 
    try f (c)
    finally c.close

Using it is dead simple. The example, below, consumes an input stream from a URLConnection. Instead of connection.getInputStream you could create any arbitrary stream, of course (or, more generally, any arbitrary closeable object).

val bytes = closer (connection.getInputStream) { istream =>
        val bytes = new ByteArrayOutputStream ()
        val buffer : Array [Byte] = new Array (1024)
        Iterator.continually (istream read buffer).takeWhile (_ > 0).foreach (bytes write (buffer, 0, _))
        bytes.toByteArray
    }

This version will operate on anything with a close method (needn't implement Closeable or anything else).

def autoClose[R <: {def close()}, T](resource: R)(use: R => T): T = {
  try use(resource)
  // Don't want an NPE here masking an exception from use.
  finally Option(resource).foreach(_.close())
}

Here are some implicit classes to do the job.

implicit class AutoCloseBracket[R <: Closeable](resource: R) {
  def autoClose[V](use: R => V): V = try use(resource) finally resource.close()
}
implicit class AutoCloseableBracket[R <: AutoCloseable](resource: R) {
  def autoClose[V](use: R => V): V = try use(resource) finally resource.close()
}
like image 39
F. P. Freely Avatar answered Sep 16 '22 16:09

F. P. Freely