In Scala, how do I get the *name* of an `object` (not an instance of a class)?
Asked Answered
L

4

22

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.

Lappet answered 21/10, 2012 at 5:25 Comment(3)
don't you already have the variable name? why do u want to do that at all?Isometry
see this too: #5051182Isometry
@Isometry 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.Faena
D
24

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
Disconsolate answered 21/10, 2012 at 5:56 Comment(6)
It also can be test.Main$Thingy$ or test.Main$Test1$2$ if object defined in other object or method.Guff
@SergeyPassichenko: So then you have to do a bit more parsing to get the value out, but the basic idea is the same.Disconsolate
@SergeyPassichenko: Included a solution in the answer. It doesn't cover objects defined in methods, but that's usually not needed.Disconsolate
Here's another peculiarity. Thingy.getClass.getName => "Thingy$" but println(Thingy.getClass.getName) prints "$line2.$read$$iw$$iw$Thingy$".. Can anyone explain this?Lappet
@Scoobie: That only happens in the REPL.Disconsolate
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 = FooGunpaper
O
32

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
Overpraise answered 21/10, 2012 at 18:55 Comment(1)
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.Trainer
D
24

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
Disconsolate answered 21/10, 2012 at 5:56 Comment(6)
It also can be test.Main$Thingy$ or test.Main$Test1$2$ if object defined in other object or method.Guff
@SergeyPassichenko: So then you have to do a bit more parsing to get the value out, but the basic idea is the same.Disconsolate
@SergeyPassichenko: Included a solution in the answer. It doesn't cover objects defined in methods, but that's usually not needed.Disconsolate
Here's another peculiarity. Thingy.getClass.getName => "Thingy$" but println(Thingy.getClass.getName) prints "$line2.$read$$iw$$iw$Thingy$".. Can anyone explain this?Lappet
@Scoobie: That only happens in the REPL.Disconsolate
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 = FooGunpaper
G
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
Good answered 4/4, 2015 at 5:21 Comment(0)
S
0
def nameOf[T](implicit ev: ClassTag[T]):String = ev.runtimeClass.getName.replace("$", "")
Shelf answered 3/12, 2020 at 13:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.