Why does Scala place a dollar sign at the end of class names? - scala

In Scala when you query an object for either its class or its class name, you'll get a rogue dollar sign ("$") at the tail end of the printout:
object DollarExample {
def main(args : Array[String]) : Unit = {
printClass()
}
def printClass() {
println(s"The class is ${getClass}")
println(s"The class name is ${getClass.getName}")
}
}
This results with:
The class is class com.me.myorg.example.DollarExample$
The class name is com.me.myorg.example.DollarExample$
Sure, it's simple enough to manually remove the "$" at the end, but I'm wondering:
Why is it there?; and
Is there anyway to "configure Scala" to omit it?

What you are seeing here is caused by the fact that scalac compiles every object to two JVM classes. The one with the $ at the end is actually the real singleton class implementing the actual logic, possibly inheriting from other classes and/or traits. The one without the $ is a class containing static forwarder methods. That's mosty for Java interop's sake I assume. And also because you actually need a way to create static methods in scala, because if you want to run a program on the JVM, you need a public static void main(String[] args) method as an entry point.
scala> :paste -raw
// Entering paste mode (ctrl-D to finish)
object Main { def main(args: Array[String]): Unit = ??? }
// Exiting paste mode, now interpreting.
scala> :javap -p -filter Main
Compiled from "<pastie>"
public final class Main {
public static void main(java.lang.String[]);
}
scala> :javap -p -filter Main$
Compiled from "<pastie>"
public final class Main$ {
public static Main$ MODULE$;
public static {};
public void main(java.lang.String[]);
private Main$();
}
I don't think there's anything you can do about this.

Although all answer that mention the Java reflection mechanism are correct this still doesnot solve the problem with the $ sign or the ".type" at the end of the class name.
You can bypass the problem of the reflection with the Scala classOf function.
Example:
println(classOf[Int].getSimpleName)
println(classOf[Seq[Int]].getCanonicalName)
=> int
=> scala.collection.Seq
=> Seq
With this you just have the same result as you have in for example Java

There are several problems with your approach:
You are using Java Reflection. Java Reflection doesn't know anything about Scala.
Furthermore, you are using Java Reflection on a Singleton Object, a concept that doesn't even exist in Java.
Lastly, you are using Java Reflection to ask for the class of a Singleton Object, but in Scala, Singleton Objects aren't instances of a class.
So, in other words: you are asking the wrong language's reflection library to reflect on something it doesn't understand and return something that doesn't even exist. No wonder you are getting nonsense results!
If you use Scala Reflection instead, the results become a lot more sensible:
import scala.reflect.runtime.{universe => ru}
def getTypeTag[T: ru.TypeTag](obj: T) = ru.typeTag[T]
object Foo
val theType = getTypeTag(Foo).tpe
//=> theType: reflect.runtime.universe.Type = Foo.type
As you can see, Scala Reflection returns the correct type for Foo, namely the singleton type (another thing that doesn't exist in Java) Foo.type.
In general, whereas Java Reflection deals mainly in classes, Scala Reflection deals in Types.
Using Scala Reflection instead of Java Reflection is not only better because Java Reflection simply doesn't understand Scala whereas Scala Reflection does (in fact, Scala Reflection is actually just a different interface for calling into the compiler, which means that Scala Reflection knows everything the compiler does), it also has the added benefit that it works on all implementations of Scala, whereas your code would break on Scala.js and Scala-native, which simply don't have Java Reflection.

This is a result of compiling to the JVM. To make an object in scala requires two classes. The "base" class and the class to make the singleton object. Because these classes can't both have the same name, the $ is appended. You could probably modify the compiler so that it won't make a $ but you will still need some way to name the generated class names.

Related

How do you create a ScalaMock stub that doesn't call the constructor of the underlying object?

Consider the following example Scala class and unit test:
class BrokenClass(s: String) {
private val len = s.length
def length(): Int = len
}
class BrokenTest extends FlatSpec with Matchers with MockFactory {
"A BrokenClass" should "stub correctly" in {
val stubThing = stub[BrokenClass]
(stubThing.length _) when () returns (10)
stubThing.length should equal (10)
}
}
In older versions of ScalaMock, this code would work. With Scala 2.12 and ScalaMock 3.6, I'm getting a NullPointerException because even though I'm creating a stub, it's still invoking the "s.length" line of the constructor of BrokenClass. So it's trying to dereference "s", which is null because I haven't passed anything to it because all I want is a stub that returns a specific value when a specific method is called.
Is there a way to create a stub without it trying to invoke the object's constructor? Why did this work in older versions?
ScalaMock generates subclasses using a macro definition.
That macro gets expanded/evaluated during the compiler run.
As mocks are subclasses, the constructors of the superclasses will be called - no exceptions.
You might be able to work around this using some cglib sorcery, but that is not something i am familiar with.
So this may have been possible in older ScalaMock versions but this feature is not coming back anytime soon with the current implementation.
another option is to actually subclass this thing yourself and mock the subclass
class NotSoBrokenClass extends BrokenClass("")
...
val nsb = mock[NotSoBrokenClass]
...
That works in some cases, but if the constructor depends on non-final method calls you'll see funny behaviour (e.g. NPEs) too.

How to do subclass reflection in trait of scala

import scala.reflect.runtime.{universe => ru}
trait someTrait{
def getType[T: ru.TypeTag](obj: T) = ru.typeOf[T]
def reflect()={
println(getType(this)) // got someTrait type, not A type.
}
}
class A extends someTrait{
}
main(){
new A().reflect()
}
When I run main function, I got someTrait type printed out.
How can I get A type in reflect function?
Using TypeTags or ClassTags, you can't (without doing extra work in every subtype, as Ramesh's answer does). Because the compiler inserts them based on static types only.
When it sees getType(this), it first infers type parameter to getType[someTrait](this), and then turns into getType[someTrait](this)(typeTag[someTrait]). You can see A is never considered and it can't be.
As the scala document says, we cant use java reflectoin since it might cause problem.
No, Scala documentation certainly doesn't say you can't use Java reflection for this. You need to understand its limitations but exactly the same applies to Scala reflection.

How to force scalac to generate a static final field?

When defining vals on a companion object like this:
object Foo { val bar = 3 }
Scala generates static final methods:
$ scalac Foo.scala && javap Foo
public final class Foo {
public static int bar();
}
Is there a way to make it generate a static field instead of a static method?
FWIW, I need it since I have existing compiled Java code and I need to preserve binary compatibility.
There is no way at the moment to have Java-like static fields in Scala whether they are final or not. See explanation here for example: Why doesn't Scala have static members inside a class?.
That's one of the reasons Akka is not written 100% in Scala: http://www.infoq.com/interviews/klang-akka
So what is Akka write in it?
Akka is not one hundred percent Scala because some constructs you
can’t really express in Scala for performance reasons, so static
fields for example, so when you need to do some tricky stuff with
concurrency you need to have static fields, so I think it’s like
ninety percent Scala and then we have some Java stuff just because we
have to.
You can do Java/Scala interop on the Java side, i.e. create some sort of adapters in your case.
There are existing implementations for static fields, but it's not clear when we'll get it: https://issues.scala-lang.org/browse/SI-4581.
I can't find a way to make this import compile: import scala.annotation.static. Maybe it's not in my Scala version or is disabled by default. Otherwise this would be the answer:
object Foo { #static final val bar: Int = 3 }

I can haz no package-private class in Scala?

Sorry for the catchy title. ;-)
I want to create a package-private class with a package-private method in Scala, so my class looks somewhat like this:
package net.java.truevfs.ext.pace
import ...
private[pace] abstract class AspectController(controller: FsController)
extends FsDecoratingController(controller) {
private[pace] def apply[V](operation: => V): V
... // lots of other stuff
}
However, if I use javap to check what the Scala compiler effectively creates, I get something like this:
$ javap -classpath target/classes net.java.truevfs.ext.pace.AspectController
Compiled from "AspectController.scala"
public abstract class net.java.truevfs.ext.pace.AspectController extends net.java.truevfs.kernel.spec.FsDecoratingController implements scala.ScalaObject{
public abstract java.lang.Object apply(scala.Function0);
...
}
This means that although the Scala compiler might respect the access restrictions, I could still call this class from any Java code, which is a clear encapsulation violation.
Am I missing something?
Is there a way to make this work as intended?
In addition to #Régis' answer, the reason Scala compiler doesn't make the class package-private is because by Scala rules it can be accessed from other packages: namely, subpackages of net.java.truevfs.ext.pace. E.g.
package net.java.truevfs.ext.pace.subpackage
import net.java.truevfs.ext.pace.AspectController
class Subclass extends AspectController { ... }
is legal in Scala, but in Java classes from net.java.truevfs.ext.pace.subpackage can't access package-private classes from net.java.truevfs.ext.pace.
You are not missing anything.
Many of the access restricitons in scala have no equivalent in java nor at the jvm level. The additional information is obviously right there in the .class file, but is there as custom annotations that only the scala compiler will interpret.
The scala object model can only partly be matched to the jvm object model, and a java compiler will only see this partial model.
I'd say that the match is pretty close and the scala compiler does a very good job at java interoperability, but nothings's perfect.
Not really a 100% correct answer...
You can make a package object if I want to do some fancy stuff in there with a private class. The package object is accessed like any other package.
The class MyClass is package private to that package object.
It's not package private however.
package object com.jasongoodwin.foo {
private class MyClass
class AnotherClass {
val myClass = new MyClass
}
}

How to create annotations and get them in scala

I want to define some annotations and use them in Scala.
I looked into the source of Scala, found in scala.annotation package, there are some annotations like tailrec, switch, elidable, and so on. So I defined some annotations as them do:
class A extends StaticAnnotation
#A
class X {
#A
def aa() {}
}
Then I write a test:
object Main {
def main(args: Array[String]) {
val x = new X
println(x.getClass.getAnnotations.length)
x.getClass.getAnnotations map { println }
}
}
It prints some strange messages:
1
#scala.reflect.ScalaSignature(bytes=u1" !1* 1!AbCaE
9"a!Q!! 1gn!!.<b iBPE*,7
Ii#)1oY1mC&1'G.Y(cUGCa#=S:LGO/AA!A 1mI!)
Seems I can't get the annotation aaa.A.
How can I create annotations in Scala correctly? And how to use and get them?
FWIW, you can now define scala annotation in scala 2.10 and use reflection to read them back.
Here are some examples:
Reflecting Annotations in Scala 2.10
Could it have something to do with retention? I bet #tailrec is not included in the bytecode getting generated.
If I try to extend ClassfileAnnotation (in order to have runtime retention), Scala tells me that it can't be done, and it has to be done in Java:
./test.scala:1: warning: implementation restriction: subclassing Classfile does not
make your annotation visible at runtime. If that is what
you want, you must write the annotation class in Java.
class A extends ClassfileAnnotation
^
I think you can only define annotations in Java now.
http://www.scala-lang.org/node/106
You can find a nice description of how annotations are to be used in Scala in Programming Scala.
So you can define or use annotations in scala. However there is at least one limitation:
Runtime retention is not quite possible. In theory you should subclass ClassFileAnnotation to achieve this, but currently scalac reports the following warning if you do it:
"implementation restriction: subclassing Classfile does not make your annotation visible at runtime. If that is what you want, you must write the annotation class in Java."
It also means that your code is fine as it is (at least as fine as it is currently possible in Scala), but the annotation is on the class only during compile time. So you could use it e.g. in compiler plugins, but you will not be able to access it runtime.
With scala 2.11.6, this works to extract values of a annotation:
case class MyAnnotationClass(id: String) extends scala.annotation.StaticAnnotation
val myAnnotatedClass: ClassSymbol = u.runtimeMirror(Thread.currentThread().getContextClassLoader).staticClass("MyAnnotatedClass")
val annotation: Option[Annotation] = myAnnotatedClass.annotations.find(_.tree.tpe =:= u.typeOf[MyAnnotationClass])
val result = annotation.flatMap { a =>
a.tree.children.tail.collect({ case Literal(Constant(id: String)) => doSomething(id) }).headOption
}