13

I am looking at Akka related typesafe activator code and the following construct intrigued me:

Companion object:

object MarkerActor {
  sealed trait MarkerMessage
  case object Stop extends MarkerMessage
   ..
  def objectMethod = print("hi from companion object")
}

Companion class: it imports the companion object methods:

class MarkerActor extends Actor with ActorLogging {
    import MarkerActor._   // Comment this line to compare w or w/o import available

    objectMethod  // just to see if 'visible' within companion class

    override def receive = {
      case Stop => {

So.. that is a bit surprising. Why is there not a "special relationship" between the companion class/object allowing the class to "see" the object methods automatically?

Update I was a bit skeptical on this, and so went ahead and commented out the "import MarkerActor._" This resulted in "Symbol not found: Stop" errors in the Companion Class. So .. the import really is required.

WestCoastProjects
  • 58,982
  • 91
  • 316
  • 560
  • I think it actually imports the types. – Tobias Brandt May 16 '14 at 21:27
  • No, I commented out the import statement and then the case objects were marked as "Cannot resolve symbol Stop" – WestCoastProjects May 16 '14 at 21:29
  • `Stop` is of type `Stop.type`. The Scala spec says that private members of the companion object are visible in the class, but does that include types? If types inside the companion object are not visible in the class, then you cannot use `Stop` because its type would be private. – Tobias Brandt May 16 '14 at 21:37
  • Those include types, yes. In any case I have also shown a method "objectMethod" that displays the same visibility (/not visible) behavior. – WestCoastProjects May 16 '14 at 21:44
  • Interesting. Apparently, a method being in the companion object just means you can access it, but it isn't automatically imported. You should be able to make `objectMethod` private and still call it from the class. – Tobias Brandt May 16 '14 at 21:46
  • Correct - the private does not hide the companion's method from the class. – WestCoastProjects May 16 '14 at 21:50
  • 2
    So, there's your answer: class and object have a special relationship, they can access their respective privates. However, they still need to qualify the access with the class/object name. – Tobias Brandt May 16 '14 at 21:51
  • I am going to leave this question open to hear if there were more to the relationship details, to potentially get more insight here. But I will go ahead and upvote your last comment in any case. – WestCoastProjects May 16 '14 at 21:53
  • 1
    Tobias' answer is correct. Follow the links on this thread for some additional insights from a few years back as to why this is the case. http://www.scala-lang.org/old/node/2411 – Chris May 17 '14 at 03:42
  • Well it is Viktor Klang asking that question, so I am in good company! – WestCoastProjects May 17 '14 at 03:51
  • So to summarize the thread from the link from @Chris: it was discussed at the "highest" level (including Odersky) and the (far-from unanimous) consensus was the auto-import of companion artifacts into the class were not preferred. It was a split decision. – WestCoastProjects May 17 '14 at 03:55
  • @Chris I would like to accept as the answer your post - since it goes to the heart of the decision - which was a split decision judgement call. – WestCoastProjects May 18 '14 at 23:06
  • I just converted it to an answer for you. – Chris May 18 '14 at 23:29

1 Answers1

21

Several years ago there was a discussion on whether to implicitly import all companion object members into their parent classes. The decision made at the time, which still makes sense today, was to require an explicit import, since it is easier to add an additional import than to remove an undesired one. Here is the full discussion.

Chris
  • 2,885
  • 18
  • 25
  • the nabble link in the scala-lang.org discussion didn't work for me here is an alternative link http://scala-language.1934581.n4.nabble.com/Companion-object-visibility-in-Eclipse-plugin-td1941958.html – Jean Jun 17 '15 at 16:39