3

Clarity needed in determining the scope of Scala's constructor parameter

As per this link https://alvinalexander.com/scala/how-to-control-visibility-constructor-fields-scala-val-var-private#comment-13237, whenever a constructor parameter is labelled as private, then no getter and setter methods will be created. But the code I have provided here works fine even though the parameter is labelled as private. I went through this StackOverflow link Do scala constructor parameters default to private val?. This one & the above contradicts. Can someone please explain. The code segment is, in fact, available in the StackOverflow link.

class Foo(private val bar: Int) {
    def otherBar(f: Foo) {
        println(f.bar) // access bar of another foo
    }
}

The below line runs fine:

val a = new Foo(1)
a.otherBar(new Foo(3))

It prints 3.

As per the first link, the code should result in compile error because the parameter is private.

2 Answers 2

3

If you have a look at the scala language specification the private modifier allows access

from within the directly enclosing template and its companion module or companion class.

To allow access only from your inside the instance you can use the modifier private[this]. The code

class Foo(private[this] val bar: Int) {
  def otherBar(f: Foo) {
    println(f.bar) // access bar of another foo
  }
}

results in

[error] .../src/main/scala/sandbox/Main.scala:9:17: value bar is not a member of sandbox.Foo
[error]       println(f.bar) // access bar of another foo
[error]                 ^
[error] one error found
Sign up to request clarification or add additional context in comments.

6 Comments

Why is private [this] val bar better than just bar?
If you only use bar it is just a constructor parameter, no member variable will be created in class Foo. The original poster asked why it was possible to access a private member variable from another instance
So why is having a member variable better than not having a member variable? Is it something to do with reflection? What other reason is there for creating a member that isn't needed?
If you don't need a member variable, don't use it. I agree with that. But as far as I understood, the original question was about the accessibility rules for a private member in Scala.
Thanks Harald for you answer! When we say "private val bar: Int" in the constructor parameter (without 'this'), a private field named 'bar' will be created with getter and setter methods. If this is correct,then the link I provided in my question needs to be corrected.
|
3

If you want a constructor parameter that is only visible inside the class, don't make it a member, just make it a normal function parameter:

class Foo(bar: Int) {
  def otherBar(f: Foo) {
    println(f.bar) // Fails: value bar is not a member of Foo
  }
}

All the code inside the constructor can still access bar, but it is not a member of Foo and therefore is not visible outside the constructor.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.