Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Here's an implementation that's also a little more generic:</p> <pre><code>import scala.language.experimental.macros object WithIdExample { import scala.reflect.macros.Context def withId[T, I](entity: T, id: I): T = macro withIdImpl[T, I] def withIdImpl[T: c.WeakTypeTag, I: c.WeakTypeTag](c: Context)( entity: c.Expr[T], id: c.Expr[I] ): c.Expr[T] = { import c.universe._ val tree = reify(entity.splice).tree val copy = entity.actualType.member(newTermName("copy")) val params = copy match { case s: MethodSymbol if (s.paramss.nonEmpty) =&gt; s.paramss.head case _ =&gt; c.abort(c.enclosingPosition, "No eligible copy method!") } c.Expr[T](Apply( Select(tree, copy), params.map { case p if p.name.decoded == "id" =&gt; reify(id.splice).tree case p =&gt; Select(tree, p.name) } )) } } </code></pre> <p>It'll work on any case class with a member named <code>id</code>, no matter what its type is:</p> <pre><code>scala&gt; case class Bar(arg0: String, id: Option[Int]) defined class Bar scala&gt; case class Foo(x: Double, y: String, id: Int) defined class Foo scala&gt; WithIdExample.withId(Bar("bar", None), Some(2)) res0: Bar = Bar(bar,Some(2)) scala&gt; WithIdExample.withId(Foo(0.0, "foo", 1), 2) res1: Foo = Foo(0.0,foo,2) </code></pre> <p>If the case class doesn't have an <code>id</code> member, <code>withId</code> will compile—it just won't do anything. If you want a compile error in that case, you can add an extra condition to the match on <code>copy</code>.</p> <hr> <p>Edit: As Eugene Burmako just pointed out <a href="https://twitter.com/xeno_by/status/270495257152593920" rel="noreferrer">on Twitter</a>, you can write this a little more naturally using <code>AssignOrNamedArg</code> at the end:</p> <pre><code>c.Expr[T](Apply( Select(tree, copy), AssignOrNamedArg(Ident("id"), reify(id.splice).tree) :: Nil )) </code></pre> <p>This version won't compile if the case class doesn't have an <code>id</code> member, but that's more likely to be the desired behavior anyway.</p>
    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