क्या स्केल 2.10 में एक विधि परिभाषा पेड़ (यानी, DefDef
) के बाईं ओर MethodSymbol
को चालू करने का कोई सुविधाजनक तरीका है?एक विधि प्रतीक और शरीर से एक विधि परिभाषा पेड़ बनाना
उदाहरण के लिए, मान लीजिए कि मैं एक मैक्रो बनाना चाहता हूं जो एक विशेषता का एक उदाहरण लेगा और कुछ डीबगिंग कार्यक्षमता के साथ उस विशेषता के सभी तरीकों को लपेट लेगा। निम्नलिखित मैं लिख सकते हैं:
import scala.language.experimental.macros
import scala.reflect.macros.Context
object WrapperExample {
def wrap[A](a: A): A = macro wrap_impl[A]
def wrap_impl[A: c.WeakTypeTag](c: Context)(a: c.Expr[A]) = {
import c.universe._
val wrapped = weakTypeOf[A]
val f = Select(reify(Predef).tree, "println")
val methods = wrapped.declarations.collect {
case m: MethodSymbol if !m.isConstructor => DefDef(
Modifiers(Flag.OVERRIDE),
m.name,
Nil, Nil,
TypeTree(),
Block(
Apply(f, c.literal("Calling: " + m.name.decoded).tree :: Nil),
Select(a.tree, m.name)
)
)
}.toList
//...
}
मैं एक नई अज्ञात वर्ग विशेषता को लागू करता है में इन तरीकों चिपके हुए और फिर उस वर्ग आप अगर आप एक पूरा काम कर उदाहरण here पा सकते हैं instantiating की बोरिंग व्यापार elided है ' रुचि रखते हैं
अब मैं यह लिख सकते हैं, उदाहरण के लिए:
scala> trait X { def foo = 1; def bar = 'a }
defined trait X
scala> val x = new X {}
x: X = [email protected]
scala> val w: X = WrapperExample.wrap[X](x)
w: X = [email protected]
scala> w.foo
Calling: foo
res0: Int = 1
scala> w.bar
Calling: bar
res1: Symbol = 'a
तो यह काम करता है, लेकिन केवल बहुत सरल में मामलों, यह नहीं होगा यदि विशेषता पैरामीटर सूची के साथ तरीकों, पहुँच संशोधक, एनोटेशन के साथ है, आदि
जो मैं वास्तव में चाहता हूं वह एक ऐसा कार्य है जो एक विधि प्रतीक और नए शरीर के लिए एक पेड़ लेगा और DefDef
लौटाएगा। मैं हाथ से एक लिखना शुरू किया है, लेकिन यह इस तरह बारीकियों सामान का एक बहुत शामिल है:
List(if (method.isImplicit) Some(Flag.IMPLICIT) else None, ...)
कौन सा, कष्टप्रद वर्बोज़, और त्रुटि प्रवण है। क्या मुझे नए प्रतिबिंब एपीआई में ऐसा करने के लिए कुछ अच्छा तरीका याद आ रहा है?
धन्यवाद (और +1), लेकिन क्या होगा यदि मैं जिस विशेषता को लपेटना चाहता हूं वह लाइब्रेरी से है? उस मामले में मैं उपर्युक्त दृष्टिकोण से फंस गया हूं, है ना? –
आह मैं देखता हूं कि आपका क्या मतलब है। आप इस एपीआई का उपयोग कर सकते हैं: https://github.com/scalamacros/kepler/blob/0acb8a30c379f268e8a3e1340504530493a1a1dc/src/reflect/scala/reflect/api/Trees.scala#L2480। हमने इसे 2.10.1 में बहिष्कृत कर दिया है, लेकिन आप इसे देख सकते हैं कि इसे कैसे कार्यान्वित किया गया है: https://github.com/scalamacros/kepler/blob/0acb8a30c379f268e8a3e1340504530493a1a1dc/src/reflect/scala/reflect/internal/Trees.scala#L975 । –