Erik van Oosten
Erik van Oosten

Reputation: 1728

How can one combine overriding with stackable traits in Scala?

In Swing and Wicket applications it is normal to override methods in classes that are provided by the framework. For example:

val form = new Form("form") {
  override def onSubmit() { println("Form was submitted") }
}

Where for the example Form can be defined as:

abstract class Form(id: String) {
  def onSubmit()
  def error(msg: String) { println(msg) }
}

Many form implementation need error handling. For this I created a stackable trait:

trait FormErrorHandler extends Form {
  abstract override def onSubmit() {
    try super.onSubmit()
    catch { case e: Exception => error("error during submit " + e.getMessage) }
  }
}

If I now try to combine this I get compiler errors:

val form = new Form("form") {
  override def onSubmit() { println("Form was submitted") }
} with FormErrorHandler // DOES NOT COMPILE

I worked around it with:

class MyForm extends Form("form") {
  override def onSubmit() { println("Form was submitted") }
}
val form = new MyForm with FormErrorHandler

but it just doesn't read as well; I have to name a class that is normally anonymous.

Any suggestions to make this look nice? Would the syntax construct I tried make sense for a future Scala version?

Upvotes: 1

Views: 376

Answers (1)

Rex Kerr
Rex Kerr

Reputation: 167891

You're correct that you cannot both create an anonymous class that overrides methods and then, afterwards, mix in a trait. But there's an easy way around it: define another method in the trait (e.g. abstract def mySubmit) that you then fill in in the child (or have it do something useful by default and override it if you want to).

Then you can mix the error handler in first and override the new method in the anonymous block.

Upvotes: 1

Related Questions