Getting the name of an object

Hi,

I have code which extends a class I made as so:

object StackUserProtocol extends ProtocolLang with App {
in(“State1”) goto “State2”

end()
}
ProtocolLang is a class with the “in”, “goto” and “end” methods.
Is there a way I can get the name “StackUserProtocol” from inside ProtocolLang?

> object StackUserProtocol
object StackUserProtocol

> val nameWithDollar = StackUserProtocol.getClass.getName
val nameWithDollar: String = StackUserProtocol$

> val name = nameWithDollar.substring(0, nameWithDollar.length -1)
val name: String = StackUserProtocol

Alternatively, if you make your object a case object, toString will suffice.

Hi, sorry, I don’t think I explained my question very well. I meant can I get the name without knowing the name of the object in advance?

How this code would actually be used:
The user would write the StackUserProtocol object themselves and then during compilation, the ProtocolLang class should get the name of the object.

I don’t know if that is possible since the only way that ProtocolLang knows about the object is that it is extending it.

Here be dragons, but

class Bar() {
  def implementationName = this.getClass().getName().stripSuffix("$")
}

object Impl extends Bar()

Then Bar has access to (the mangled version of) implementationName. Be aware that unmangling is not generally possible, especially if there are $ characters as part of the objects own name or its enclosing class.

2 Likes

Do you mean like this?

Welcome to Scala 2.13.3 (OpenJDK 64-Bit Server VM, Java 11.0.8).
Type in expressions for evaluation. Or try :help.

> :paste
// Entering paste mode (ctrl-D to finish)

trait ProtocolLang {
def myName: String = {
val rawName = getClass.getSimpleName
if(rawName.endsWith("$")) {
rawName.substring(0, rawName.length - 1)
} else {
rawName
}
}

def printMyName: Unit = println(s"ProtocolLang knows my name is $myName")
}

object StackUserProtocol extends ProtocolLang with App {

}

// Exiting paste mode, now interpreting.

trait ProtocolLang
object StackUserProtocol

> StackUserProtocol.printMyName
ProtocolLang knows my name is StackUserProtocol
2 Likes

Amazing! I didn’t think there would be such a simple way of doing this.

martijnhoekstra, I tried your technique and it seems to work even if I add many $ to the object name (??). So “$$Stack$UserProtocol$” worked fine. Are there other potential problems with this method?

curoli Your method also seems to work fine :smiley:

Don’t know if it’s a problem but

scala> object A { class B { object C extends Bar } }
object A

scala> println((new A.B).C.implementationName)
$line59.$read$$iw$A$B$C
1 Like

Fair point. Actually, in that particular case, curoli’s code works just fine and gives “C” :))

If the class is specialized, there may be more mangling going on. Also, when the name contains non-alphanumeric characters.

1 Like