Saya ingin memprogram makro Scala yang mengambil instance kelas kasus sebagai argumen. Semua objek yang bisa diteruskan ke makro harus mengimplementasikan sifat penanda tertentu.
Cuplikan berikut menunjukkan sifat penanda dan dua contoh kelas kasus yang menerapkannya:
trait Domain
case class Country( id: String, name: String ) extends Domain
case class Town( id: String, longitude: Double, latitude: Double ) extends Domain
Sekarang, saya ingin menulis kode berikut menggunakan makro untuk menghindari beratnya refleksi runtime dan ketidakamanan threadnya:
object Test extends App {
// instantiate example domain object
val myCountry = Country( "CH", "Switzerland" )
// this is a macro call
logDomain( myCountry )
}
Makro logDomain
diimplementasikan dalam proyek berbeda dan terlihat mirip dengan:
object Macros {
def logDomain( domain: Domain ): Unit = macro logDomainMacroImpl
def logDomainMacroImpl( c: Context )( domain: c.Expr[Domain] ): c.Expr[Unit] = {
// Here I would like to introspect the argument object but do not know how?
// I would like to generate code that prints out all val's with their values
}
}
Tujuan makro adalah untuk menghasilkan kode yang - saat runtime - menampilkan semua nilai (id
dan name
) dari objek tertentu dan mencetaknya seperti yang ditunjukkan berikutnya:
id (String) : CH
name (String) : Switzerland
Untuk mencapai hal ini, saya harus secara dinamis memeriksa argumen tipe yang diteruskan dan menentukan anggotanya (vals). Kemudian saya harus membuat AST yang mewakili kode yang membuat keluaran log. Makro harus berfungsi terlepas dari objek spesifik apa yang mengimplementasikan sifat penanda "Domain" yang diteruskan ke makro.
Pada titik ini saya tersesat. Saya akan sangat menghargai jika seseorang dapat memberi saya titik awal atau mengarahkan saya ke beberapa dokumentasi? Saya relatif baru mengenal Scala dan belum menemukan solusi di dokumen Scala API atau panduan Makro.