Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>The key insight here is that the constructor arguments names <em>are</em> available, as they are the names of the fields created by the constructor. So <strong>provided that the constructor does nothing with its arguments but assign them to fields</strong>, then we can ignore it and work with the fields directly.</p> <p>We can use:</p> <pre><code>def setFields[A](o : A, values: Map[String, Any]): A = { for ((name, value) &lt;- values) setField(o, name, value) o } def setField(o: Any, fieldName: String, fieldValue: Any) { // TODO - look up the class hierarchy for superclass fields o.getClass.getDeclaredFields.find( _.getName == fieldName) match { case Some(field) =&gt; { field.setAccessible(true) field.set(o, fieldValue) } case None =&gt; throw new IllegalArgumentException("No field named " + fieldName) } </code></pre> <p>Which we can call on a blank person:</p> <pre><code>test("test setFields") { val p = setFields(new Person(null, null, -1), Map("firstname" -&gt; "Duncan", "lastname" -&gt; "McGregor", "age" -&gt; 44)) p.firstname should be ("Duncan") p.lastname should be ("McGregor") p.age should be (44) } </code></pre> <p>Of course we can do better with a little pimping:</p> <pre><code>implicit def any2WithFields[A](o: A) = new AnyRef { def withFields(values: Map[String, Any]): A = setFields(o, values) def withFields(values: Pair[String, Any]*): A = withFields(Map(values :_*)) } </code></pre> <p>so that you can call:</p> <pre><code>new Person(null, null, -1).withFields("firstname" -&gt; "Duncan", "lastname" -&gt; "McGregor", "age" -&gt; 44) </code></pre> <hr> <p>If having to call the constructor is annoying, Objenesis lets you ignore the lack of a no-arg constructor:</p> <pre><code>val objensis = new ObjenesisStd def create[A](implicit m: scala.reflect.Manifest[A]): A = objensis.newInstance(m.erasure).asInstanceOf[A] </code></pre> <p>Now we can combine the two to write </p> <pre><code>create[Person].withFields("firstname" -&gt; "Duncan", "lastname" -&gt; "McGregor", "age" -&gt; 44) </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload