2

Is there a way to dynamically instantiate a Scala case class having one or more default parameters specified?

I'm looking for the dynamic (reflection-based) equivalent of this:

case class Foo( name:String, age:Int = 21 )
val z = Foo("John") 

Right now if I try this I get an exception:

val const = Class.forName("Foo").getConstructors()(0)
val args = Array("John").asInstanceOf[Array[AnyRef]]
const.newInstance(args:_*)

If I add a value for age in my parameter array, no problem.

Chris Seymour
  • 83,387
  • 30
  • 160
  • 202
Greg
  • 10,696
  • 22
  • 68
  • 98
  • possible duplicate of [Instantiating a case class with default args via reflection](http://stackoverflow.com/questions/16939511/instantiating-a-case-class-with-default-args-via-reflection) – senia Jun 08 '13 at 21:12
  • exact dupe of http://stackoverflow.com/questions/14034142/how-do-i-access-default-parameter-values-via-scala-reflection – som-snytt Jun 09 '13 at 15:00

2 Answers2

1

You can get default parameters as methods of object in runtime.

In case of constructor parameters - companion object methods (scala 2.9.3).

$ echo 'class Test(t: Int = 666)' > test.scala
$ scalac -Xprint:typer test.scala
...
<synthetic> def init$default$1: Int @scala.annotation.unchecked.uncheckedVariance = 666

You can't rely on the name of this method. (scala 2.10.1):

scala> Test.$lessinit$greater$default$1
res0: Int = 666

I don't know how to get default parameters for constructor, but in case of case class you could get apply method default parameters. See this answer.

Community
  • 1
  • 1
senia
  • 37,745
  • 4
  • 88
  • 129
  • @som-snytt: the name is different in `2.9.3` and `2.10.1`, so one should not use the name, but generate in using `defaultGetterName`. – senia Jun 09 '13 at 17:31
  • @som-snytt: your comment makes me want to create method `\`\``. – senia Jun 09 '13 at 19:41
0

Argument with default value are a compile-time thing. The compiler will feed in the default value for a call where the parameter is missing. No such thing with reflection, all the less with java reflection, which is not aware at all of default arguments.

Didier Dupont
  • 29,398
  • 7
  • 71
  • 90