Scala protected object - scala

In Scala, if I create an object and companion class, identifiers declared with the protected modifier can be accessed from the class if the object is imported:
object Foo {
protected val X = 42
}
class Foo {
import Foo._
def getX(): Int = X
}
However, the protected identifier cannot be accessed from a subclass of the class Foo:
class Bar extends Foo {
import Foo._
def getX(): Int = X * 2
}
I get a compile-time error in Bar.
Other then (implied) public, is there any access modifier I can place on X so that it can be accessed from subclasses of its companion, but not from other classes, including other classes in the same package?

That's because only the class Foo is companion to the object Foo.
Here, the difference between private and protected meaningless, since the object Foo is a singleton, which means there isn't any other object that has the same class as object Foo (Foo.type).
Access restriction in Scala is package-based, so the short answer is no. You could make a forwarder on the base class, though, unless you need it to be available without an instance.
In your place, however, I'd go back to the design board.

In such cases, I would suggest using a package private modifier, like below:
object Foo {
private[your_package] val X = 42
}
The value will still be visible to everybody else in the package.

To achieve the same thing, One solution to this problem can be:
class Bar extends Foo {
import Foo._
override def getX(): Int = super.getX * 2
}

Related

Access modifier location explanation in scala

I discovered that we can use access modifier before class as well as after class name. For example, I have 2 classes as follows
package com.company.package.sub_package
protected class Animal1{
def makeSound(): Unit = println("Bow ow")
}
object Animal1{
def main(args: Array[String])
{
val animal = new Animal2()
animal.makeSound()
}
}
package com.company.package.sub_package
class Animal2 protected{
def makeSound(): Unit = println("Meow")
}
object Animal2{
def main(args: Array[String])
{
val animal = new Animal1()
animal.makeSound()
}
}
Here an error shows up in Animal1 main method saying Animal2 cannot be accessed in object Animal1.
If I extend Animal2 class, the sub class is able to access the parent class.
What I understand from this is if we write protected after the class name, it is not available to classes in same package and if I right it before class, it is available to all classes in the package, only to its sub classes, is this a correct assumption? What is the exact significance of location of an access modifier?
What is the exact significance of location of an access modifier?
The access modifier always comes before the thing whose access it modifies.
In your first example, protected comes before the class Animal1, so it regulates access to the class.
In your second example, protected comes before the primary constructor, so it regulates access to the primary constructor. (Note: it's not obvious that it comes before the primary constructor because Animal2 has an empty primary constructor, but the Scala Language Specification says that if there is no parameter list for a class, an empty () parameter list is inserted.)
So, your Animal2 class is actually equivalent to
class Animal2 protected () {
def makeSound(): Unit = println("Meow")
}
A typical reason for restricting access to the primary constructor is to control instance creation either through auxiliary constructors or factory methods in the companion module.
You can find the specification for access modifiers of the primary constructor in section 5.3 Class Definitions of the Scala Language Specification.
The access modified before a class is like the access modifier for any other value in a class. It specifies the visibility of that class outside the containing class and in subclasses.
The access modifier after the class applies to the constructor and specifies the visibility of the constructor outside the companion object for that class
Typically it is used to hide the default constructor:
class Positive private(val i: Int)
object Positive {
def apply(i: Int): Positive = new Positive(math.abs(i))
}
You can access the i field of a Positive but it can never be negative.

Force inheriting class to implement methods as protected

I've a got a trait:
trait A {
def some: Int
}
and an object mixing it in:
object B extends A {
def some = 1
}
The question is, is there a way to declare some in A in a way that all inheriting objects have to declare the some method as protected for example? Something that would make the compiler yell at the above implementation of some in B?
UPDATE:
Just a clarification on the purpose of my question: Within an organization, there are some software development standards that are agreed upon. These standards, for example 'The some method is to always be declared as private when inheriting from trait A', are in general communicated via specs or documents listing all the standards or via tools such as Jenkins, etc... I am wondering if we could go even further and have these standards right in the code, which would save a lot of time correcting issues raised by Jenkins for example.
UPDATE 2:
A solution I could think of is as follows:
abstract class A(
protected val some: Int
){
protected def none: String
}
Use an abstract class instead of a trait and have the functions or values that I need to be protected by default passed in the constructor:
object B extends A(some = 1) {
def none: String = "none"
}
Note that in this case, some is by default protected unless the developer decides to expose it through another method. However, there will be no guarantee that, by default, none will be protected as well.
This works for the use case I described above. The problem with this implementation is that if we have a hierarchy of abstract classes, we would have to add the all the constructor parameters of the parent to every inheriting child in the hierarchy. For example:
abstract class A(
protected val some: Int
)
abstract class B(
someImp: Int,
protected val none: String
) extends A(some = someImp)
object C extends B(
someImp = 1,
none = "none"
)
In contrast, using traits, we could have been able to simply write:
trait A{
protected val some: Int
}
trait B extends A{
protected val none: String
}
object C extends B{
val some = 1
val none = "none"
}
I don't see any straight way to restrict subclasses from choosing a wider visibility for inherited members.
It depends on why you want to hide the field some, but if the purpose is just to forbid end-users from accessing the field, you can use a slightly modified form of the cake pattern:
trait A {
trait A0 {
protected def some: Int
}
def instance: A0
}
object B extends A {
def instance = new A0 {
def some = 5
}
}
Yeah, it looks nasty but the compiler will yell when someone tries to do:
B.instance.some
Another version of this solution is just to do things like in your example (adding protected to the member "some" in A), but to never expose directly a reference of type B (always return references of type A instead)

Make inherited val public

There exists (outside of my code)
trait Foo {
protected val bar = 0
}
I want have a class FooImpl that extends Foo and makes bar public.
I heard that subclasses could increase the visibility of their inherited members.
How do I do this?
I tried
class FooImpl extends Foo {
override val logger = super.logger
}
But got the error:
super may be not be used on value logger
It works if you make logger a def instead of a val.
trait Foo {
protected def logger = 0
}
class FooImpl extends Foo {
override val logger = super.logger
}
If Foo isn't defined by you, you may be out of luck outside of a solution involving reflection.
See this and this.
You could increase visibility of methods.
When you declare field with wider visibility you declare new field.

Can I use "this" in a companion object?

In a companion object, I want to have a field recording all the instances instantiated from the companion class (it is abstract), can I do that?
Especially, I thought this would reference to any instances of the subclass, but it won't compile when I use it in a companion object.
You'd need to code it yourself, for instance (not thread safe):
abstract class C {
// executed by all subclasses during construction
C.registerInstance(this)
}
object C {
private val instances = ListBuffer[C]()
def registerInstance(c: C) {
instances += c
}
}
this in an object (doesn't matter if it's a companion object or not) refers to the object. E.g.
scala> object A { def foo = 1; def bar = this.foo }
defined module A
scala> A.bar
res0: Int = 1

scala: How to get the class in its own constructor

I need access to the Class of the object being constructed in its own constructor (for various detailed reasons I don't think are relevant to my question).
I want something like this
class Foo(val i:Int)
class Bar extends Foo(this.getClass.getName.length)
val b = new Bar
println(b.i)
to print 3 ("Bar".length). But it doesn't. If the code above is inside some other object, "this" refers to that object. If the code above is not inside some other object (just in some package), the compiler complains with
error: this can be used only in a class, object, or template
class Bar extends Foo(this.getClass.getName)
^
CLARIFICATION: I can't change Foo to use a val in its body instead of its constructor because Foo's API already exists and is fixed (so, yes, i must be a constructor parameter). It needs an integer argument at constructor time, but that integer can only be calculated with access to the Class.
(I know the example above is still silly and degenerate. If people care, I can explain in detail why I need the class in my real project, http://code.google.com/p/factorie)
Surely, the class of the object being constructed is known to the compiler and runtime during construction. With what syntax can I get it? (Is there no such syntax? If not, I wonder why. I'm surprised it there doesn't seem to be a simple, standard way to get this.)
A lazy val solves this problem:
object Early
{
abstract class Foo { val name: String }
class Bar extends Foo { lazy val name = getClass.getName }
def
main(args: Array[String]): Unit = {
val b = new Bar
println(b.name)
}
}
Yields:
% scala Early
Early$Bar
Not sure whether this is possible in a clean way. If you like hacks you could do
class Bar extends Foo((new Exception).getStackTrace.apply(0).getClassName)
However I strongly advertise against it!
This appears to satisfy your requirement without using a lazy val and without altering the base class:
scala> class Base(val name: String)
defined class Base
scala> class Derived extends Base(classOf[Derived].getName)
defined class Derived
scala> new Derived name
res0: String = Derived
You are going to have to explain your motivation for wanting to do this. Does name have to be a constructor parameter of Foo or can it be an abstract member? Does it have to be a val or will a def do.
You can do this
class Foo(val name: String)
class Bar extends Foo("") {
override val name = getClass.getName
}
and new Bar().name will give Bar
But I suspect that if your true motivation is known then there is a better way to do what you really want.
How about
class Bar extends Foo(classOf[Bar].getName.length)
What about this:
class Foo(otherName: Option[String] = None) {
val name = otherName.getOrElse(this.getClass.getName)
}
class Bar extends Foo()
val b = new Bar
println(b.name)