Scala case class private apply method (repl bug?)

in Scala2.10.0 REPL

Welcome to Scala version 2.10.0 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_13). Type in expressions to have them evaluated. Type :help for more information. scala> case class A private(i:Int) defined class A scala> A(1) res0: A = A(1) 

But if you compile

 $ scala -version Scala code runner version 2.10.0 -- Copyright 2002-2012, LAMP/EPFL $ cat Main.scala package foo case class A private (i:Int) object Main extends App{ println(A(1)) } $ scalac Main.scala Main.scala:6: error: constructor A in class A cannot be accessed in object Main println(A(1)) ^ one error found 

A.apply(1) is a compilation error.

is it a Scala2.10.0 REPL error?

FYI Scala2.9.2 REPL follows

 Welcome to Scala version 2.9.2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_13). Type in expressions to have them evaluated. Type :help for more information. scala> case class A private(i:Int) defined class A scala> A(1) <console>:10: error: constructor A in class A cannot be accessed in object $iw A(1) ^ 
+7
source share
3 answers

It definitely looks like a REPL error.

Note that the constructor is correctly marked as private (in other words, new A(1) does not compile as expected), it is not so simple factory ( A.apply ).

+2
source

I see ... You think you are calling the constructor when you write A(1) . You do not. You call the factory added to you in the automatically created (public) companion object and its public apply method.

Adding

My day will be repeatedly mistaken ...

In 2.10.0 REPL:

 scala> object REPL { case class CC1 private(i: Int); val cc1_1 = CC1(23) } <console>:7: error: constructor CC1 in class CC1 cannot be accessed in object REPL object REPL { case class CC1 private(i: Int); val cc1_1 = CC1(23) } 
-2
source

REPL has one huge semantic difference wrt is a regular compiler.

Think about what it means to be able to do this:

 scala> val v1 = 23 v1: Int = 23 scala> val v1 = 42 v1: Int = 42 

Could you do this in compiled Scala code? Of course not, that would be a forbidden double definition.

How does REPL do this? In fact, each line you enter is in a more nested area. The appearance of the override is the actual shading. As if you did it:

 object REPL1 { val v1 = 23 object REPL2 { val v1 = 42 object REPL3 { // Next REPL line here... } } } 

So how do you get companions? Place an explicit object (or other structure forming the area) around them. And remember, no empty lines. REPL will stop accepting input for a given โ€œlineโ€ or โ€œblockโ€ when you do this.

-3
source

All Articles