views:

72

answers:

2

I have a small conundrum when it comes to Scala properties.

Various blogs and tutorials tell me that this:

class Something
{
    var foo = 1
}

...can be specified as...

class Something
{
    private var _field = 1

    def foo = _field
    def foo_(foo: Int) = _field = foo
}

This makes perfect sense to me, when doing assignment the compiler looks for a name_ method. Problem is it doesn't seem to work for me.

In the following real-world code (same thing happens in other classes as well):

class Camera
{
  private var _position = Vector2.zero

  def position: Vector2 = _position
  def position_(position: Vector2) =
  {
    // Do boring transforms.
    _position = position // position shadows outer scope so this does work.
  }
}

// ...
val camera = new Camera
camera.position = Vector2(10, 0)

I get an error:

error: value position_= is not a member of Camera camera.position = Vector(10, 0)

Instead I need to call it the following way to actually make it work: camera.position_(Vector2(10, 0)) which is neither beautiful nor readable.

In other scenarios, for example when trying to have public getters and private setters I faced the same problem.

What am I doing wrong?

Using scalac 2.8.0 on Java HotSpot VM 1.6

+7  A: 

Your setters need to be named foo_= and position_=. If you name them foo_ and position_ the compiler doesn't recognize them as setters.

Dave Griffith
Thank you. I should pay more attention to the error messages :)
Skurmedel
+5  A: 

The signature to implement is:

def position_=(position: Vector2): Unit

So you want to correct your code like this:

def position_=(position: Vector2) { _position = position }
huynhjl
Thanks! ... sigh, sadly that is rather obvious when I think about it. Can only upvote one so I took the quickest answer.
Skurmedel
Replacing the equals with braces is unnecessary. The compiler will automatically infer `Unit` from the assignment `_position = position`, and automatically give the `position_=` method the correct return type of `Unit`.
Ken Bloom