2013-01-01 10 views
9

Scala 2.9.xでは、func()関数を書いて、func()が実行された関数の名前をFUNC Cプリプロセッサマクロのように戻しました。私はScala2.10では、仕事をするために例外をスローするよりもエレガントなものを書くことができるはずであることを理解しています。Scalaの__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 
      ^
関連する問題