Узнать имя метода в Groovy

Есть ли способ в Groovy узнать имя вызываемого метода?

def myMethod() {
    println "This method is called method " + methodName
}

Это, в сочетании с утиной типизацией, позволило бы получить довольно краткий (и, вероятно, трудный для чтения) код.


person pchronz    schedule 11.04.2012    source источник
comment
Взгляните на эту тему. stackoverflow.com/questions/9540678/   -  person Ritesh M Nayak    schedule 11.04.2012
comment
Спасибо, такого я не нашел!   -  person pchronz    schedule 11.04.2012


Ответы (2)


Нет, как и в случае с Java, нет собственного способа сделать это.

Вы можете написать преобразование AST, чтобы аннотировать метод, и это может установить локальную переменную внутри метода.

Или вы можете сделать это старым добрым Java-способом создания stackTrace и найти правильный StackTraceElement с помощью чего-то вроде:

import static org.codehaus.groovy.runtime.StackTraceUtils.sanitize

def myMethod() {
  def name = sanitize( new Exception().fillInStackTrace() ).stackTrace.find {
    !( it.className ==~ /^java_.*|^org.codehaus.*/ )
  }?.methodName

  println "In method $name"
}

myMethod()
person tim_yates    schedule 11.04.2012

Groovy поддерживает возможность перехвата всех методов с помощью механизма invokeMethod GroovyObject.

Вы можете переопределить invokeMethod, который по существу будет перехватывать все вызовы методов (для перехвата вызовов существующих методов класс дополнительно должен реализовать интерфейс GroovyInterceptable).

class MyClass implements GroovyInterceptable {
    def invokeMethod(String name, args) {
        System.out.println("This method is called method $name")
        def metaMethod = metaClass.getMetaMethod(name, args)
        metaMethod.invoke(this, args)
    }

    def myMethod() {
        "Hi!"
    }
}

def instance = new MyClass()
instance.myMethod()

Также вы можете добавить эту функциональность в существующий класс:

Integer.metaClass.invokeMethod = { String name, args ->
    println("This method is called method $name")
    def metaMethod = delegate.metaClass.getMetaMethod(name, args)
    metaMethod.invoke(delegate, args)
}

1.toString()
person Arturo Herrero    schedule 11.04.2012