10

I'm currently learning Scala, and just discovered the way to create custom field getters/setters. I have a simple example working:

class Thing(private val a:Int){ override def toString = "Thing[" + a + "]" private var _value = a def value = _value def value_= (newVal:Int) = _value = newVal } 

On the console I can do:

scala> var t = new Thing(2) t: dylan.code.Thing = Thing[2] scala> t.value res1: Int = 2 scala> t.value = 3 scala> t.value res2: Int = 3 

Now I'm trying to bring this concept to a slightly more complicated example; I'll try to whittle the code down to what's relevant:

abstract class CellExpression[Type] extends Publisher[CellUpdateEvent[Type]] with Subscriber[CellUpdateEvent[Type], CellExpression[Type]]{ protected var cachedValue: Type = recalculateValue() protected def recalculateValue(): Type protected def changeValue(newValue: Type):Unit = { val oldValue = value() if(newValue != oldValue){ cachedValue = newValue publish(new CellUpdateEvent(this, oldValue, newValue)) } } def value() = cachedValue def notify(pub: CellExpression[Type], event: CellUpdateEvent[Type]) = changeValue(recalculateValue()) } //.... class CellVariable[Type](private val initialValue:Type) extends CellExpression[Type]{ cachedValue = initialValue protected def recalculateValue() = { cachedValue } override def toString = "CellVariable[" + value + "]" def value_= (newValue:Type) = {changeValue(newValue)} } 

As far as I can tell, I've done what I need to in order to be able to treate value as a field via its getter and setter. But when I try it out in the console, I get:

scala> var i = new CellVariable(2) i: dylan.code.CellVariable[Int] = CellVariable[2] scala> i.value = 3 <console>:11: error: reassignment to val i.value = 3 ^ 

What have I done wrong, and how can I fix it?

2 Answers 2

12

I actually stumbled onto the solution.

The line where I declare my value function: def value() = cachedValue is the culprit. If I remove the parentheses to make the line def value = cachedValue everything seems to work as I expected.

Sign up to request clarification or add additional context in comments.

1 Comment

Exactly. The assignment notation only works if a corresponding parameterless getter (without (), as you noted) is defined (though implicit parameters are allowed). If you only want to provide a setter with no getter, what I'd do is def value(implicit ev: Nothing) = error("Not supposed to be called").
-1

You cannot change values in Scala. A value is assigned once and only once. If you want to do this then you need to use variables instead of values. In other words, change the declaration from val to var.

The problem is inside one of your class definitions and may be on a line without val because I believe that if you neglect to declare a name, then Scala assumes that it is a value and therefore immutable.

Not sure what you want getters and setters for though. Scala enables you to ignore all of that Java overhead.

It is probably the line that says cachedValue = initialValue because it is not declared with var anywhere in that class. The definition in the other class is a different name because it is in a different scope. You would have to say something like class.varname to change a variable defined in another class.

3 Comments

I understand the concept of vals and vars, and I thought I was careful to not use any vals within my classes. The one line that may be suspect is the one where I say cachedValue = initialValue- that is meant to be an override of the value for the protected var in the CellExpression class. And the reason I want the getter/setter is to have side effects, e.g. notify Subscribers of a change in a Cell's value when the value is set. I'm not sure what you mean by "all that Java overhead"- I'm using the Scala syntactic sugar of value_= for my setter, as opposed to setValue...
I thought one of the reasons why Java gurus are moving to Scala is that it allows you to get away from all that boilerplate getter and setter stuff that you need in Java. What do you gain from writing Scala getters and setters? Isn't there an easier way?
The only benefit that I know of for sure is the ability to say v.value = 3 as opposed to v.setValue(3) and still get side effects if you want them. I see it as syntactic sugar, but as far as side effects go, I can't see any other way to get them besides magic.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.