Can't get an access to a companion object's field
Asked Answered
T

2

6

I'm wondering, why can't a class get an access to a companion object's field?

class MyClass {
  println(val1) // not found, why?
}

object MyClass {
  val val1 = "str"
}

It should, it should even have an access to the private fields of object MyClass.

Tall answered 20/11, 2013 at 17:41 Comment(0)
U
10

You can do that by using MyClass.val1 instead of just val1. I guest that's done to denote that companion object members can be accessed from anywhere (with default modifiers).

Unavoidable answered 20/11, 2013 at 18:2 Comment(10)
it should not be so because it's a companion object.Tall
@Alex: I guess that's by design and was reasoned along the lines of this comment: "The thing is, it's a lot easier to import something into your namespace if you want it than it is to unimport if you don't. And personally I already have enough problems with shadowing" (from scala-lang.org/old/node/2411.html#comment-8493). If you think so because you are reading "Programming in Scala", you might just have misunderstood it (see comment scala-lang.org/old/node/2411.html#comment-8427).Ics
hasn't that been differently recently? I think I have used it without importing previously.Tall
@Alex: you could just import companion object's methods like this: class MyClass { import MyClass._; println(val1) };Bloat
@senia, my last question is not about that. Of course, I can do that, but the object doesn't necessarily have to be a companion object.Tall
@senia, and since it's a companion object, it shouldn't require importing itself to "companion" class.Tall
@Alex: why not? There could be methods with the same name in object and class. For instance: List.apply(1).apply(0). Importing by default leads to name collisions.Bloat
@senia, has that always been so? If I recall correctly, previously there wasn't a need to import the fields of a companion object, they were accessible by default.Tall
@Alex: the oldest scala version available on scala-lang.org is 2.5.0.final. And you have to import companion object methods manually in that version.Bloat
@Alex: you could see all changes about companion objects in Changelog. The only change about companion object was in Version 2.1.8 (23-Aug-2006) Relaxation of Private Access. Before that version you couldn't even call private methods of companion object in class.Bloat
Q
6

It's debatable that a class "should" have access to its companion object fields by default. Consider the not uncommon case where the companion object's apply method is used as a factory, and the object itself has an apply method to do something different. It would get confusing to read the code and know which method was meant! Roland Ewald made a comment to another answer quoting http://www.scala-lang.org/old/node/2411.html#comment-8493 which sums it up nicely:

"The thing is, it's a lot easier to import something into your namespace if you want it than it is to unimport if you don't. And personally I already have enough problems with shadowing."

And that gives the answer. Use import thus:

class MyClass {
  import MyClass._
  println(val1) // Should see it now!
}

object MyClass {
  val val1 = "str"
}
Qua answered 16/7, 2014 at 21:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.