Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala: Accessing package visible methods through structural types outside the package

This does not work as expected (since I am trying to call a package private run from outside Services):

object Services {
 class HelloPrinter {
   private[Services] def run = "Hello"
  }  
}

val obj = new Services.HelloPrinter

But, surprisingly this works:

val obj: {def run: String} = new Services.HelloPrinter
obj.run

I would say, its a bug in the compiler since as HelloPrinter does not match the structural type because of package visibility rules, it should not compile at all!

Here is a case where the program compiles but it throws a runtime exception (java.lang.NoSuchMethodException):

class HelloPrinter {
  private[HelloPrinter] def run = "Hello"
}  

val obj: {def run: String} = new HelloPrinter
obj.run

Is this a language feature or rule I am missing or legitimately a bug in Scala?

like image 286
pathikrit Avatar asked Jul 08 '15 20:07

pathikrit


1 Answers

On the JVM level visibility scoped to surrounding instances/types does not exist. The Scala compiler will generate a public method in this case and handle this visibility internally.

If you use structural types the compiler will reflectively access the members of this type. It will not check Scala-specific visibility flags but only the ones defined in the Java bytecode.

You did not mention which version of the Scala compiler you are using but I assume that this is a bug in your specific version. I get the same result as Jasper-M when trying to compile it. The reason is that the method that is generated by the compiler is actually prefixed with the type name, i.e. HelloPrinter$$run in this case. The following code will execute:

val x: { def HelloPrinter$$run: String  } = new HelloPrinter
x.run

Again the Scala compiler just generates a public method and manages visibility internally. It is not a feature but rather a bug that the compiler does not check the Scala-internal visibility for structural types.

like image 169
Moritz Avatar answered Oct 16 '22 05:10

Moritz