raffian
raffian

Reputation: 32076

Groovy, get enclosing function's name?

I'm using Groovy 1.8.4, trying to get the name of the enclosing function...

def myFunction() {
  println functionName??
}

I've tried delegate, this, owner, Groovy complains no such objects found.

I also tried the Java hack new Exception().getStackTrace()[0].getMethodName(), but that just prints newInstance0

Upvotes: 13

Views: 13759

Answers (5)

Kevin Klassen
Kevin Klassen

Reputation: 56

Today there are several ways to do this.

See: https://www.baeldung.com/java-name-of-executing-method

In my case, what worked best was this appoach:

new Object(){}.getClass().getEnclosingMethod().getName();

Upvotes: 2

Bertl
Bertl

Reputation: 625

@CompileStatic
class LogUtils {
    // can be called the Groovy or Java way
    public static String getCurrentMethodName(){
        StackTraceElement[] stackTrace = StackTraceUtils.sanitize(new Throwable()).stackTrace
        stackTrace[2].methodName != 'jlrMethodInvoke' ? stackTrace[2].methodName : stackTrace[3].methodName
    }
}

Upvotes: 1

Robert Fey
Robert Fey

Reputation: 1807

import org.codehaus.groovy.runtime.StackTraceUtils

def getCurrentMethodName(){
  def marker = new Throwable()
  return StackTraceUtils.sanitize(marker).stackTrace[1].methodName
}

def helloFun(){
   println( getCurrentMethodName() )
}

helloFun()

output:

helloFun

Upvotes: 18

Matias Bjarland
Matias Bjarland

Reputation: 171

How about groovy's StackTraceUtils.sanitize? Here's a quick example:

import org.codehaus.groovy.runtime.StackTraceUtils

class A {
  def methodX() {
    methodY()
  }

  def methodY() {
    methodZ()
  }

  def methodZ() {
    def marker = new Throwable()
    StackTraceUtils.sanitize(marker).stackTrace.eachWithIndex { e, i ->
        println "> $i ${e.toString().padRight(30)} ${e.methodName}"
    }
  }

}

new A().methodX()

The output of the above when pasted into a standalone script test.groovy is as follows:

$ groovy test.groovy 
> 0 A.methodZ(test.groovy:13)      methodZ
> 1 A.methodY(test.groovy:9)       methodY
> 2 A.methodX(test.groovy:5)       methodX
> 3 A$methodX.call(Unknown Source) call
> 4 test.run(test.groovy:21)       run

the sanitize method filters out all groovy internal mumbo jumbo from the trace and the clean trace together with ...stackTrace.find { } should give you a decent start.

Upvotes: 17

doelleri
doelleri

Reputation: 19682

You can get to it via the stacktrace, I've been able to get it via:

groovy:000> def foo() { println Thread.currentThread().stackTrace[10].methodName }
===> true
groovy:000> foo()
foo
groovy:000> class Foo {                                                             
groovy:001>   def bar() { println Thread.currentThread().stackTrace[10].methodName }
groovy:002> }
===> true
groovy:000> new Foo().bar()
bar

Upvotes: 4

Related Questions