Logister
Logister

Reputation: 1904

Scala: how to reference class properties from nested class

Suppose I have the following class:

class MyProg(prop: Int) {
  var K = prop

  def myFunc() {
    class UtilityClass() {
      //does stuff that uses K
    }
  }
}

I want to be able to have UtilityClass access the K parameter without (1) explicitly passing K, and (2) without allowing MyProg.K value to be mutated by operations inside of UtilityClass.

E.g. I have tried:

class MyProg(prop: Int) {
  var K = prop

  def myFunc() {
    class UtilityClass() {
      K = MyProg.this.K
      //does stuff that uses K
    }
  }
}

But this (1) seems to operate as a pass by reference, and anything done in the utility class to K now changes the MyProg.K value, and (2) MyProg.this.K syntax doesn't make any sense.

What is the correct way for UtilityClass to access K? How the heck does MyProg.this.K mean anything?

Upvotes: 0

Views: 400

Answers (2)

Tim
Tim

Reputation: 27421

The problem is this line:

K = MyProg.this.K

This does not do anything, it just re-assigns K to itself. All references to K inside UtilityClass are references to K in MyProg. So when you update K in UtilityClass you change the value of K in MyProg.

I think you want this:

var K = MyProg.this.K

Now there is a new K in UtilityClass which can be updated without affecting the K in MyProg. By using the same name you hide the outer K from the rest of UtilityClass and protect it from being changed.

Of course the warnings about using var also apply, so look for a way to make K a val if possible. If K is a val then you can just use it in UtilityClass directly.

Upvotes: 1

themathmagician
themathmagician

Reputation: 515

Of course if you use a val instead of a var, your problem is solved, right?

So I assume, that you need to have the field as a mutable variable in your class.

You can prevent outside manipulation of the variable by using the access modifier private, and define use a public getter, so other classes can access it's value:

 class MyProg(prop: Int) {
  private var _K = prop
  def K = _K
}

val peekAtK = new MyProg(4).K           
//> peekAtK  : Int = 4

The private modifier prohibits all other classes from accessing the variable, however, a nested class exists in the same lexical scope, and it will always be able to access the field K.

Upvotes: 2

Related Questions