2

I want to make an instance with variable designating some trait like below, which gives you an error. Is there anyway to do this in scala?

var traitRefer = classOf[SomeTrait]
var a = new SomeClass() with traitRefer
Elonoa
  • 467
  • 7
  • 19
  • It has no sense. This code is the same like in java: `Class> traitRefer = SomeTrait.class; class a extends SomeClass implements traitRefer` traitRefer is just a variable!!!! – Andrzej Jozwik Mar 14 '12 at 07:50

3 Answers3

7

I don't think there is a way to do this other than reflection, because this is not typesafe. What you could do is create an instance with a specific trait mixed in in a pattern matching. E.g.

kind match {
  case "Foo" => new SomeClass with Foo
  case "Bar" => new SomeClass with Bar
}
drexin
  • 24,225
  • 4
  • 67
  • 81
3

Excellent question! What you're missing in your understanding is what happens at compile time versus what happens at run time.

When the Scala compiler encounters an expression such as new Foo with Bar, at compile time it generate an anonymous inner class that is essentially the same as class Anonymous extends Foo with Bar. Then the compiler does all of its magic about stackable traits and what-not to produce the output that you want. The base class and extended traits must be defined at compile time; you cannot define them at runtime.*

Since the trait you wish to mix-in isn't known until runtime, the compiler doesn't know what to generate for the anonymous class.

I'm assuming that you the trait is taking advantage of the stackable traits to change the behavior of SomeClass. As an alternative, you can use the decorator pattern, and select your decorator at runtime.

(*) What you can do at runtime is generate the bytecode for a new class. There are numerous ways of doing this, including embedding the Scala compiler. This, however, is not for the feint of heart. There's surely an easier way to accomplish what you're trying to do.

leedm777
  • 23,444
  • 10
  • 58
  • 87
  • Yes I wanted to dynamically apply some traits, and now I know why it can't be done. The design patter could be useful. Thanks all – Elonoa Mar 15 '12 at 10:57
2

I think it's impossible in that way (exclude reflection). See more here. You can do this:

type Ref = SomeTrait
var a = new SomeClass with Ref

But I think it's not what you want

Community
  • 1
  • 1
Sergey Passichenko
  • 6,920
  • 1
  • 28
  • 29