Reputation: 1393
I'm trying create an instance of a class and mix in certain traits based on certain conditions. So Given:
class Foo
trait A
trait B
I can do something like
if (fooType == "A")
new Foo with A
else if (footType == "B")
new Foo With B
That works just fine for a simple case like this. My issue is that multiple traits can be mixed into the same instance based on other conditions, and on top of that the class being instantiated has a fair amount of parameters so this leads to a pretty ugly conditional block.
What I would like to do is determine the traits to be mixed in before hand something like this (which I know is not legal scala code):
val t1 = fooType match {
case "a" => A
case "b" => B
}
val t2 = fooScope match {
case "x" => X
case "y" => Y
}
new Foo with t1 with t2
Where A, B, X, and Y are all previously defined traits, and fooType and fooScope are inputs to my function. I'm not sure if there is anything I can do which is somewhat similar to the above, but any advice would be appreciated.
Thanks
Upvotes: 2
Views: 1620
Reputation: 11518
A couple of ideas to throw in the mix...
With the complicated code full of conditionals that you speak of, get those to put together a list of possible combinations. This list can then be used to create all the classes. Very simple example:
(for(a <- Seq("A", "B"); b <- Seq("X", "Y")) yield
s"class Foo$a$b extends $a with $b").mkString("\n")
which'll produce the following:
class FooAX extends A with X
class FooBX extends B with X
class FooAY extends A with Y
class FooBY extends B with Y
Then simply:
val ax = new FooAX()
which is nice because it's very strongly typed and everyone'll know exactly what type it is everywhere without much casting/inference headache.
There's an interesting non-reflection/classloader technique here:
https://github.com/b-studios/MixinComposition
which takes in traits as parameters and then simply delegate to the appropriate trait.
Upvotes: 1
Reputation: 2353
I believe what you want to do is not possible. In Scala the type of an object has to be known at compile time, so new Foo with A
works but new Foo with t1
will not because t1
is resolved only at run time.
Upvotes: 2