Anonymous Mixins in Scala 3

I’d like to mix-in a trait at the point of instantiation to define new behavior.

Based on this discussion, this seems to be one approach:

class Ball(value:Int):
  def number = value
  def isMagic = number == 8

trait Magicify:
  this:Ball => 
  override def number = 8; 
  def wasMagic:Boolean = ??? // access pre-override value?

List(Ball(1),Ball(8)).map { b => (b.number, b.isMagic) } // As expected
val m = { object $anon extends Ball(1) with Magicify; $anon }
(m.number, m.isMagic) // (8, true)

Is there a more canonical way to do an anonymous mix-in – other than {object $anon extends ...; $anon}?
Also, is there a way to call the original (non-overridden) method number from the mix-in?

See code here:

val n = new Ball(9) with Magicify
println(n)
(n.number, n.isMagic)

Thanks – the solution is literally new in Scala 3.
Is there a way for me to get something like super.number in the trait?

I suggest you post a new question and explain what it is that you want t do.

The use of super does not seem to make sense in a trait, but it will work in a class that extends something else.

I would

object m extends Ball(1) with Magicify

but I see in your linked discussion that JS prefers the new.

The story on super is not super:

VerifyError on super call

It is an implementation restriction on Scala 2 and obviously also Scala 3.

But I think it demonstrates that certain feature interactions remain obscure or under-exercised, and it’s easier to find an idiomatic construction than figure out (for the nth time) how traits work with inheritance.

1 Like