2013-01-01 13 views
9

स्कैला 2.9.एक्स में, मैंने func फ़ंक्शन लिखा है जो मुझे फ़ंक्शन का नाम वापस देता है जहां func() को FUNC सी प्रीप्रोसेसर मैक्रो की तरह निष्पादित किया जाता है। मैं समझता हूं कि Scala2.10 में मुझे नौकरी करने के लिए अपवाद फेंकने से कुछ और अधिक सुरुचिपूर्ण लिखने में सक्षम होना चाहिए।स्कैला में __FUNC__ मैक्रो 2.10

मैं यह कैसे कर सकता हूं? आपकी सहायता के लिये पहले से ही धन्यवाद।

object TestMyLog extends App { 
    val MatchFunc = """(.+)\(.+""".r 

def func(i_level: Int): String = { 
    val s_rien = "functionNotFound" 
    try { 
    throw new Exception() 
    } catch { 
    case unknwn => unknwn.getStackTrace.toList.apply(i_level).toString match { 
      case MatchFunc(funcs) => funcs.split('.').toList.last 
     case _ => s_rien 
    } 
    } finally { 
    s_rien  
    } 
} 

def tracedFunction1 = func(1) 
def tracedFunction2 = func(1) 

println(tracedFunction1) 
assert(tracedFunction1=="tracedFunction1") 
println(tracedFunction2) 
assert(tracedFunction2=="tracedFunction2") 
} 

उत्तर

4

मैं एक अपवाद के बिना यह करने के बारे में यकीन नहीं है, लेकिन आप वास्तव में फेंक/स्टैक ट्रेस प्राप्त करने के लिए अपवाद को पकड़ने की जरूरत नहीं है:

(new Exception).getStackTrace.toList 
+1

तुम भी अपवाद बनाए बिना एक स्टैकट्रेस प्राप्त कर सकते हैं:। वहाँ थ्रेड पर एक getStackTrace() विधि है, तो तुम कर सकते हो Thread.currentThread() getStackTrace.toList –

1

इस तरह से आप को ओवरलोड चाहिए funName प्रत्येक Function की धर्मार्थियों के लिए: Function1, Function2, आदि शायद कुछ गुरु मदद करेंगे?

// define macro 
import scala.language.experimental.macros 
import scala.reflect.macros.Context 
object Macros { 
    def funName(xs: Function0[_]) = macro funName_impl 
    def funName_impl(c: Context)(xs: c.Expr[Function0[_]]) = { 
    c.literal(xs.tree.children.head.toString.split("\\.").last) 
    } 
} 

// exec (in a next compile run) 
def haha: Unit = println("Function name: " + Macros.funName(haha _)) 
haha 
+1

आप धोखा दे रहे हैं, तो आप गुजर रहे हैं मैक्रो में कार्य ... – pedrofurla

+0

सहमत हैं, मैक्रोज़ की मेरी समझ दूर से बहुत दूर है, लेकिन मैं सुधार करूंगा ^) – idonnie

8
import scala.reflect.macros.Context 
import scala.language.experimental.macros 

def impl(c: Context) = { 
    import c.universe._ 
    c.enclosingMethod match { 
    case DefDef(_, name, _, _, _, _) => 
     c.universe.reify(println(c.literal(name.toString).splice)) 
    case _ => c.abort(c.enclosingPosition, "no enclosing method") 
    } 
} 

scala> def printEnclosingMethod = macro impl 
defined term macro printEnclosingMethod: Unit 

scala> def foo = printEnclosingMethod 
foo: Unit 

scala> foo 
foo 

scala> printEnclosingMethod 
<console>:32: error: no enclosing method 
       printEnclosingMethod 
      ^
संबंधित मुद्दे