Toby Eggitt
Toby Eggitt

Reputation: 1872

Scala implement abstract base and mix in traits in anonymous class

Given:

abstract class A { def show: Unit }
trait T extends A {
  abstract override def show: Unit = {
    print(" T"); super.show; print(" xT")
  }
}
trait U extends A {
  abstract override def show: Unit = {
    print(" U"); super.show; print(" xU")
  }
}
class C extends A {
  def show: Unit = print(" C")
}

I can do:

new C with T with U show

But, it "feels" (given Scala's propensity for shortened syntaxes and anonymous stuff in general) like I might be able to instantiate my mixed in class from an anonymous form. Something on the lines of

// doesn't work like this at least:
val a = new { def show { print("Anon")}} with T with U
a show

But I have entirely failed to determine if I'm simply using the wrong syntax, or if this is simply not possible. Can someone tell me how this should be done, or if it definitely is not possible?

Upvotes: 2

Views: 344

Answers (2)

leyren
leyren

Reputation: 534

Isn't this what you want?

val a = new T with U {override def show { print("Anon")}}

Syntax is pretty much the same as with declaring a new class, first the extensions/mixins, then the body.

Upvotes: 0

Andrey Tyukin
Andrey Tyukin

Reputation: 44908

I don't think this is possible.

The following two proposals are as close as I can get.

Use Constructor with Mixins

The following solution requires an additional helper class D, but the end result looks almost as your fictional syntax, except that you need one additional character for D, and you have to use round parentheses instead of curly braces:

import scala.language.postfixOps

abstract class A { def show: Unit }
trait T extends A {
  abstract override def show: Unit = {
    print(" T"); super.show; print(" xT")
  }
}
trait U extends A {
  abstract override def show: Unit = {
    print(" U"); super.show; print(" xU")
  }
}
class C extends A {
  def show: Unit = print(" C")
}

new C with T with U show

class D(s: => Unit) extends A {
  def show = s
}

// that's pretty close, isn't it?
val a = new D(print("hurray!")) with T with U
a show

Just hide the class in a block

If you just don't want to litter the namespace with classes that you use only once, then just enclose the class in a block:

val a = {
  class D extends A {
    def show = println("NoPollution")
  }
  new D with T with U
}
a show

What you wanted is to "eliminate the useless variable D" in the above "class-valued compile-time-evaluated-expression", but I don't see how one could do that.

Upvotes: 2

Related Questions