3

I'm finding myself writing a lot of (sort of) boilerplate code. For example say I have the following traits

trait Foo {
  def x: Int
}

trait Bar {
  def y: Boolean
  def z: String
}

Then I want a case class that does no more or less than implement these.

case class MyClass(x: Int, y: Boolean, z: String) extends Foo with Bar

This doesn't seem annoying, but now imagine that my traits have a dozen defs each and that the names x, y, and z are much longer. Writing the case class out means I have to rewrite all of these as arguments of MyClass.

Is there a way to generate the x: Int, y: Boolean, z: String constructor part automatically based on the traits I extend?

Alec
  • 31,829
  • 7
  • 67
  • 114
  • Well, you can override def with def from your case class. In that case You would not have to generate these vals in the first place. Also does all the implementations of your trait have val implementation of its def? If that's the case than why would you have it as def in the first place and not a val? – tkachuko Jun 22 '16 at 23:24
  • @tkachuko Suppose that I did have `val` everywhere instead of `def`, how does that help? – Alec Jun 22 '16 at 23:27
  • it helps to get into the context you are trying to solve. You need some kind of macro tooling: did you check libraries mentioned here: http://stackoverflow.com/questions/22850340/dynamically-creating-case-classes-with-macros ? – tkachuko Jun 23 '16 at 00:05

1 Answers1

5

I think what you are looking for is an annotation macro that can handle this work for you. You would then invoke this macro by writing something like this:

@FieldsFromTraits
case class MyClass extends Foo with Bar

Annotation macros can then rewrite your case class with information from the traits.

A library that does something similar is MetaRest. You might try to adapt that implementation. I'll see if I can't put something together tonight.

Mark Kegel
  • 4,476
  • 3
  • 21
  • 21
  • Wow! This is exactly what I was thinking about. I think I'm gonna give adapting that implementation a go. – Alec Jun 23 '16 at 00:12