Reputation: 6579
The following Scala code does not compile in the Scala REPL 2.11.6:
object Foo {
val DefaultSize: Int = 10
}
class Foo(size: Int = Foo.DefaultSize)
The compile error is:
value DefaultSize is not a member of object Foo
class Foo(size: Int = Foo.DefaultSize)
Tested with Scala 2.11. This is particularly strange, since it follows exactly the accepted answer (in year 2012) here: Use method return value as default constructor parameter in Scala, which nowadays does not compile, neither. So how to achieve the intended behavior?
Upvotes: 2
Views: 368
Reputation: 76
As explained in Programming in Scala, this is because the Scala REPL creates a new nested scope for each new statement you type in. This implies your code is interpreted as:
object Foo {
val DefaultSize: Int = 10
}
{
class Foo(size: Int = Foo.DefaultSize)
}
While the same book mentions that both the class and its companion object must be defined in the same source file, it seems that they furthermore must be in the same scope, since the code block above does not compile with scalac
.
I know two ways to work around this in the REPL. As mentioned by others, you could enter :paste
mode before defining the class and companion object. Alternatively, you could put both into the same scope, e.g., by defining them inside an object:
object My {
object Foo {
val DefaultSize: Int = 10
}
case class Foo(size: Int = Foo.DefaultSize)
}
Now you can use Foo
as expected:
scala> new My.Foo()
res0: My.Foo = Foo(10)
scala> new My.Foo(20)
res1: My.Foo = Foo(20)
(I made class Foo
a case class
to get concise REPL results in the last code block. The answer works without this change, however.)
Upvotes: 3