Here is a little 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" }
In the first line we get
too many arguments for method apply: (index: Int)Char in class StringOps
What happens when you define the signature of the case class, you define the signature of the constructor (when called with a new one) and the apply method in the companion object (when called without a new one),
When you put the default value in the argument, (Network () in your code and B (3, 5) in mine), this code will be compiled both in the context of the constructor and the method of applying the companion object.
As you determined the session of the companion object, the apply method is automatically added to this object. It happens that Network () in your companion object means Network.apply () in the network object that you defined there, and that means line B with the value "anyway" in my code.
What is really strange is that the default expression has different meanings, but also in the context of the constructor and the apply method. In this case, you may get a different behavior depending on whether you are calling with a new one or not.
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 the test will print
A(B(7,2)) A(B(3,4))
There are easy workarounds for your particular problem.
network: Network = models.Network(),
will work, obviously, because then itโs clear that you want the network to be in the packet, and not in the Session object.
network: Network = new Network(),
will work too, because with the new one the compiler will look for the type of network, not the value of the network. In a companion object session, the Network value is obscured by the local declaration, but the network type is not.
IMO, the first (models.Network) is understandable.
PS. I checked the spec and I believe that this weird behavior matches that. Namely, (5.3.2) the application method propagates inside the companion object with the same list of parameters as the constructor. This includes the default values, which will then be compiled inside the companion object.