0
votes

I want to get a simple class name regardless if the class is defined in the interpreter or in a scala code file. You can't get a simple name from a class defined in the interpreter (see here). As a result, I tried to create a method that would just get the fully qualified name, split it by ., and grab the last string:

def simpleNameOf(i: AnyRef) = i.getClass.getName.split('.').last

However, here is when things got weird.

scala> def simpleNameOf(i: AnyRef) = i.getClass.getName.split('.').last
simpleNameOf: (i: AnyRef)String

scala> simpleNameOf(new Human)
res25: String = $read$Human

scala> var h = new Human
h: Human = Human@fdad4ab

scala> h.getClass.getName
res27: String = Human

scala> h.getClass.getName == "Human"
res28: Boolean = false

scala> h.getClass.getName.length
res29: Int = 44

scala> h.getClass.getName.split('.')
res30: Array[String] = Array($line102, $read$Human)

scala> "Human".split('.')
res31: Array[String] = Array(Human)

So how in the heck is the string Human from getClass.getName 44 characters long? Where did $line102 & $read$Human come from?

This is Scala 2.10.4

1

1 Answers

3
votes

This is another use case for -Yrepl-class-based:

$ scala
Welcome to Scala version 2.11.2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_11).
Type in expressions to have them evaluated.
Type :help for more information.

scala> class Foo
defined class Foo

scala> classOf[Foo].getSimpleName
java.lang.InternalError: Malformed class name
  at java.lang.Class.getSimpleName(Class.java:1317)
  ... 33 elided

scala> :q
$ scala -Yrepl-class-based
Welcome to Scala version 2.11.2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_11).
Type in expressions to have them evaluated.
Type :help for more information.

scala> class Foo
defined class Foo

scala> classOf[Foo].getSimpleName
res0: String = Foo

You can turn off the output filtering of cruft:

scala> $intp.isettings.unwrapStrings
res2: Boolean = true

scala> $intp.isettings.unwrapStrings = false
$intp.isettings.unwrapStrings: Boolean = false

scala> class Bar
defined class Bar

scala> classOf[Bar].getName
res3: String = $line12.$read$$iw$$iw$Bar

If that appeals to you.

The last question: each line is wrapped in an object (or class) generally nested deeply for easy scoping of imports from history. (If you need local block semantics, you can use braces.) There is a line package for each line.

Update: There's a ticket for the getSimpleName problem, which is due IIRC just to the double "$$" in the mangled name. That happens for nested objects, not for classes (in the Scala sense).