Можно ли восстановить имя функции из функции в scala?

Я хотел бы сделать что-то вроде

def getMeASammy() {println "getMeASammy"}
def getMeADrink() {println "getMeADrink"}
def getMeASub() {println "getMeASub"}

Но я не хочу явно указывать имя функции.

Ответы

Ответ 1

scala> def currentMethodName() : String = Thread.currentThread.getStackTrace()(2).getMethodName
currentMethodName: ()String

scala> def getMeASammy() = { println(currentMethodName()) }
getMeASammy: ()Unit

scala> getMeASammy()
getMeASammy

Ответ 2

Это несколько отвратительно, но единственный поддерживаемый способ получить имя текущего метода из JVM - это создать исключение (но не выбрасывать его), а затем прочитать имя метода из трассировки стека исключений.

def methodName:String= new Exception().getStackTrace().apply(1).getMethodName()

Ответ 3

Я написал простую библиотеку, которая использует макрос для получения имени функции. Это может быть более элегантное решение, чем использование Thread.currentThread.getStackTrace()(2).getMethodName, если вы не возражаете против дополнительной зависимости:

libraryDependencies += "com.github.katlasik" %% "functionmeta" % "0.2.3" % "provided"
import io.functionmeta._

def getMeASammy() {
   println(functionName) //will print "getMeASammy"
}

Ответ 4

Nameof делает именно это и во время компиляции, поэтому нет никаких создаваемых исключений, инспектирующих трассировку стека и другие издержки отражения.

Соответствующий пример из nameof readme:

import com.github.dwickern.macros.NameOf._

  def startCalculation(value: Int): Unit = {
    println(s"Entered ${nameOf(startCalculation _)}")
  }

  // compiles to:

  def startCalculation(value: Int): Unit = {
    println(s"Entered startCalculation")
  }

В вашем случае

def getMeASammy() = println(nameOf(getMeASammy _))

Также nameOf работает с классами, атрибутами классов, типами и т.д.