I am a newbie to scala. Here is a Models.scala I am trying to write. When I run sbt package it is giving error
Models.scala:25: models.Session.Network.type does not take parameters
[error] network : Network = Network() ,
I don't understand why this error is taking place, I am not passing any parameter in when doing Network(). Can someone please help me
Here is a smaller code that reproduces your problem :
case class A(b:B = B(3, 5))
case class B(i: Int, j: Int)
object A {
val B = "whatever"
}
On the first line, we get
too many arguments for method apply: (index: Int)Char in class StringOps
What happens is that when you define the signature of the case class, you are both defining the signature of the constructor (when you call with new), and of the apply method in the companion object (when you call without new).
When you put default value in argument, (Network() in your code, and B(3, 5) in mine), this code will be compiled both in the context of the constructor and of the apply method of the companion object.
As you have defined a companion object Session, the apply method is automatically added into this object. It happens that Network() in your companion object means Network.apply() on the Network object you have defined there, and it means the string B with value "whatever" in my code.
What is really weird then is that it is possible that the default expression has different meanings, but both correct in the context of the constructor and of the apply method. In this case, you may get different behavior depending on whether you call with or without new.
Here is an example :
case class A(b:B = bb)
case class B(i: Int, j: Int)
object bb extends B(3, 4)
object A {
val bb = new B(7, 2)
}
object Test extends App {
println(A())
println(new A())
}
Running test will print
A(B(7,2))
A(B(3,4))
For your specific problem, there are easy workarounds.
network: Network = models.Network(),
will work, obviously, because it is then clear that you want Network in the package and not in object Session.
network: Network = new Network(),
will work too, because with the new, the compiler will look for a Network type and not a Network value. In companion object session, the Network value is shadowed by the local declaration, but the Network type is not.
IMO, the former (models.Network) is clearer.
PS. I checked the specification and I believe this weird behavior is in line with it. Namely, (5.3.2) an apply method is genarated inside the companion object with the same parameter list as the constructor. That includes the default values, which would then be compiled inside the companion object.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With