Inizierò con un esempio. Ecco un equivalente di List.fill
per le tuple come una macro in Scala 2.10:Documentazione di Scala 2.10 macro
import scala.language.experimental.macros
import scala.reflect.macros.Context
object TupleExample {
def fill[A](arity: Int)(a: A): Product = macro fill_impl[A]
def fill_impl[A](c: Context)(arity: c.Expr[Int])(a: c.Expr[A]) = {
import c.universe._
arity.tree match {
case Literal(Constant(n: Int)) if n < 23 => c.Expr(
Apply(
Select(Ident("Tuple" + n.toString), "apply"),
List.fill(n)(a.tree)
)
)
case _ => c.abort(
c.enclosingPosition,
"Desired arity must be a compile-time constant less than 23!"
)
}
}
}
Possiamo utilizzare questo metodo come segue:
scala> TupleExample.fill(3)("hello")
res0: (String, String, String) = (hello,hello,hello)
Questo ragazzo è un uccello strano in un paio di aspetti. Innanzitutto, l'argomento arity
deve essere un numero intero letterale, poiché è necessario utilizzarlo in fase di compilazione. Nelle precedenti versioni di Scala non esisteva alcun modo (per quanto ne so) per un metodo, anche per dire se uno dei suoi argomenti era letterale o meno in fase di compilazione.
In secondo luogo, il tipo di ritorno Product
is a lie - il tipo di ritorno statico includerà l'arità specifica e il tipo di elemento determinato dagli argomenti, come mostrato sopra.
Quindi, come potrei documentare questa cosa? Non mi aspetto il supporto di Scaladoc a questo punto, ma mi piacerebbe avere un senso delle convenzioni o delle best practice (oltre a fare in modo che i messaggi di errore in fase di compilazione siano chiari) che renderebbero l'esecuzione in un metodo macro, con il suo richieste potenzialmente bizzarre, meno sorprendenti per gli utenti di una libreria di Scala 2.10.
Le manifestazioni più maturi del nuovo sistema macro (ad esempio, ScalaMock, Slick, gli altri elencati here) sono ancora relativamente senza documenti a livello di metodo. Qualsiasi esempio o suggerimento sarebbe apprezzato, compresi quelli di altre lingue con sistemi macro simili.
Riguardo a ScalaMock, come autore, sarei molto grato per i suggerimenti su come migliorare la documentazione. ScalaMock è effettivamente un DSL, quindi documentare i singoli metodi non significa necessariamente molto. Ho cercato di documentare il DSL nel suo complesso qui: http://scalamock.org/api/index.html#org.scalamock.package e qui viene fornita la documentazione qui: http://www.paulbutcher.com/2012/10/scalamock3-passo-passo/Cosa potrei aggiungere per aiutare? –
@PaulButcher: Non intendo criticare ScalaMock e ho modificato la risposta per renderla più chiara. Ho trovato che leggere il tuo codice è estremamente utile perché ho cercato di capire i macro di Scala e penso che la documentazione di alto livello sia molto chiara. –
Nessun reato. Ma sicuramente apprezzerei qualsiasi e tutti i suggerimenti per i modi in cui potrei apportare miglioramenti. –