20

In Scala, I can declare an object like so:

class Thing

object Thingy extends Thing

How would I get "Thingy" (the name of the object) in Scala?

I've heard that Lift (the web framework for Scala) is capable of this.

Scoobie
  • 1,037
  • 2
  • 12
  • 22
  • don't you already have the variable name? why do u want to do that at all? – Shaheer Oct 21 '12 at 05:32
  • see this too: http://stackoverflow.com/questions/5050682/get-scala-variable-name-at-runtime – Shaheer Oct 21 '12 at 05:34
  • 1
    @Shaheer an object is not a variable. You're confused. When a variable points to an object, the name of the variable is not the same thing as the name of the object. – Robin Green Oct 21 '12 at 08:11

4 Answers4

30

If you declare it as a case object rather than just an object then it'll automatically extend the Product trait and you can call the productPrefix method to get the object's name:

scala> case object Thingy
defined module Thingy

scala> Thingy.productPrefix
res4: java.lang.String = Thingy
DaoWen
  • 31,184
  • 6
  • 65
  • 95
  • I like the fact that it's simple, and standard API. However, unfortunately Product does not guarantee that it will always just be the name of the object implementing it, AFAICT. – Wilfred Springer May 20 '14 at 08:23
22

Just get the class object and then its name.

scala> Thingy.getClass.getName
res1: java.lang.String = Thingy$

All that's left is to remove the $.

EDIT:

To remove names of enclosing objects and the tailing $ it is sufficient to do

res1.split("\\$").last
Kim Stebel
  • 40,545
  • 12
  • 119
  • 139
  • 5
    It also can be test.Main$Thingy$ or test.Main$Test1$2$ if object defined in other object or method. – Sergey Passichenko Oct 21 '12 at 06:02
  • @SergeyPassichenko: So then you have to do a bit more parsing to get the value out, but the basic idea is the same. – Kim Stebel Oct 21 '12 at 06:04
  • @SergeyPassichenko: Included a solution in the answer. It doesn't cover objects defined in methods, but that's usually not needed. – Kim Stebel Oct 21 '12 at 11:15
  • Here's another peculiarity. `Thingy.getClass.getName` => `"Thingy$"` but `println(Thingy.getClass.getName)` prints `"$line2.$read$$iw$$iw$Thingy$"`.. Can anyone explain this? – Scoobie Oct 21 '12 at 19:29
  • @Scoobie: That only happens in the REPL. – Kim Stebel Oct 22 '12 at 08:01
  • 7
    In 2.10, you can do it like this: scala> object Foo defined module Foo scala> import scala.reflect.runtime.universe._ import scala.reflect.runtime.universe._ scala> typeOf[Foo.type].termSymbol.name res0: reflect.runtime.universe.Name = Foo – Eugene Burmako Oct 22 '12 at 11:28
3

I don't know which way is the proper way, but this could be achieved by Scala reflection:

implicitly[TypeTag[Thingy.type]].tpe.termSymbol.name.toString
Jacek L.
  • 1,326
  • 12
  • 17
0
def nameOf[T](implicit ev: ClassTag[T]):String = ev.runtimeClass.getName.replace("$", "")
Ian Campbell
  • 19,690
  • 9
  • 20
  • 44
Jelmer
  • 773
  • 5
  • 8