Setter without getter

Hi,

It seems I can’t create a setter without a getter:

class X
{
    def x_= (value: Int): Unit = {}
}

object Main
{
    def main(args: Array[String]): Unit =
    {
        var x = new X
        x.x = 45
    }
}
$ scalac Hello.scala
Hello.scala:39: error: value x is not a member of X
        x.x = 45
          ^
one error found

I don’t see any prohibition in the language spec. Is this by design or a compiler issue?

x.x_=(45)
x_= is the name of a method

From the Scala spec, paragraph 6.15:

If x is a parameterless function defined in some template, and the same template contains a setter function x_= as member, then the assignment x = e is interpreted as the invocation x_=(e) of that setter function.

Right, but it says nothing about requiring a getter. In my example, I’m performing the assignment as described, but the compiler doesn’t accept the invocation.

Yes it does. It says a parameterless function x needs to exist. That is the getter.
Both methods def x: T0 and def x_=(t: T1): T2 need to exist in order for x = e to be interpreted as x._=(e).

OK. Thanks. I didn’t read that carefully enough.

I don’t know why that restriction exists. If you just want to do some funny stuff, but don’t want x.x to be valid code, you can add a compileTimeOnly annotation to your x method:

import scala.annotation.compileTimeOnly
class X {
  def x_=(value: Int): Unit = ()
  
  @compileTimeOnly("Not a real method.")
  def x: Int = ???
}

Mind that evaluating x.x = 42 in the REPL will no longer work, because the REPL automatically calls x.x afterwards to print the newly assigned value, which now results in a compile error.

1 Like