Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Note that this can be done much more elegantly without the <code>toString</code> / <code>c.parse</code> business:</p> <pre><code>import scala.language.experimental.macros abstract class Model { def toMap[T]: Map[String, Any] = macro Macros.toMap_impl[T] } object Macros { import scala.reflect.macros.Context def toMap_impl[T: c.WeakTypeTag](c: Context) = { import c.universe._ val mapApply = Select(reify(Map).tree, newTermName("apply")) val pairs = weakTypeOf[T].declarations.collect { case m: MethodSymbol if m.isCaseAccessor =&gt; val name = c.literal(m.name.decoded) val value = c.Expr(Select(c.resetAllAttrs(c.prefix.tree), m.name)) reify(name.splice -&gt; value.splice).tree } c.Expr[Map[String, Any]](Apply(mapApply, pairs.toList)) } } </code></pre> <p>Note also that you need the <code>c.resetAllAttrs</code> bit if you want to be able to write the following:</p> <pre><code>User("a", 1, Nil).toMap[User] </code></pre> <p>Without it you'll get a confusing <code>ClassCastException</code> in this situation.</p> <p>By the way, here's a trick that I've used to avoid the extra type parameter in e.g. <code>user.toMap[User]</code> when writing macros like this:</p> <pre><code>import scala.language.experimental.macros trait Model object Model { implicit class Mappable[M &lt;: Model](val model: M) extends AnyVal { def asMap: Map[String, Any] = macro Macros.asMap_impl[M] } private object Macros { import scala.reflect.macros.Context def asMap_impl[T: c.WeakTypeTag](c: Context) = { import c.universe._ val mapApply = Select(reify(Map).tree, newTermName("apply")) val model = Select(c.prefix.tree, newTermName("model")) val pairs = weakTypeOf[T].declarations.collect { case m: MethodSymbol if m.isCaseAccessor =&gt; val name = c.literal(m.name.decoded) val value = c.Expr(Select(model, m.name)) reify(name.splice -&gt; value.splice).tree } c.Expr[Map[String, Any]](Apply(mapApply, pairs.toList)) } } } </code></pre> <p>Now we can write the following:</p> <pre><code>scala&gt; println(User("a", 1, Nil).asMap) Map(name -&gt; a, age -&gt; 1, posts -&gt; List()) </code></pre> <p>And don't need to specify that we're talking about a <code>User</code>.</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