Tusshu
Tusshu

Reputation: 1734

How to use import statement with singleton objects

Example below is from Hello World project of Akka downloaded from instructions given here.

The example code is in AkkaQuickstart.scala file. The classes Greeter and Printer and objects with the same name are all in same file under package com.example.

in the class Greeter, there are two import statements:

import Greeter._
import Printer._

Why is there a need to import Greeter and Printer in class Greeter when all these objects are defined in the same file in the same package? They are required since the code won't compile if these imports are removed.

The Scala document on import here states the following:

"import clauses are for accessing members (classes, traits, functions, etc.) in other packages. An import clause is not required for accessing members of the same package." But in the code below, import is required even if all classes and objects are in the same package. Why is import required?

Similarly for class Printer, there is following import statement:

import Printer._

Any guidance on this topic will be appreciated.

Complete example code is given below:

//#full-example
package com.example

import akka.actor.{ Actor, ActorLogging, ActorRef, ActorSystem, Props }

//#greeter-companion
//#greeter-messages

object Greeter {
  //#greeter-messages
  def props(message: String, printerActor: ActorRef): Props = Props(new 
  Greeter(message, printerActor))
  //#greeter-messages
  final case class WhoToGreet(who: String)
  case object Greet 
 }

//#greeter-messages
//#greeter-companion

//#greeter-actor
class Greeter(message: String, printerActor: ActorRef) extends Actor {
import Greeter._    //*why is import required here?*
import Printer._    //*why is import required here?*

var greeting = ""

def receive = {
  case WhoToGreet(who) =>
    greeting = message + ", " + who
    case Greet           =>
    //#greeter-send-message
    printerActor ! Greeting(greeting)
    //#greeter-send-message
}

}
//#greeter-actor

//#printer-companion
//#printer-messages
object Printer {
  //#printer-messages
  def props: Props = Props[Printer]
  //#printer-messages
  final case class Greeting(greeting: String)
}
//#printer-messages
//#printer-companion

//#printer-actor
class Printer extends Actor with ActorLogging {
  import Printer._    //why is import required here?

  def receive = {
    case Greeting(greeting) =>
      log.info("Greeting received (from " + sender() + "): " +         
greeting)
  }
}
//#printer-actor

//#main-class
object AkkaQuickstart extends App {
  import Greeter._    //why is import required here?

  // Create the 'helloAkka' actor system
  val system: ActorSystem = ActorSystem("helloAkka")

  //#create-actors
  // Create the printer actor
  val printer: ActorRef = system.actorOf(Printer.props, "printerActor")

  // Create the 'greeter' actors
  val howdyGreeter: ActorRef =
    system.actorOf(Greeter.props("Howdy", printer), "howdyGreeter")
  val helloGreeter: ActorRef =
    system.actorOf(Greeter.props("Hello", printer), "helloGreeter")
  val goodDayGreeter: ActorRef =
    system.actorOf(Greeter.props("Good day", printer), 
  "goodDayGreeter")
  //#create-actors

  //#main-send-messages
  howdyGreeter ! WhoToGreet("Akka")
  howdyGreeter ! Greet

  howdyGreeter ! WhoToGreet("Lightbend")
  howdyGreeter ! Greet

  helloGreeter ! WhoToGreet("Scala")
  helloGreeter ! Greet

  goodDayGreeter ! WhoToGreet("Play")
  goodDayGreeter ! Greet
  //#main-send-messages
 }
 //#main-class
 //#full-example

Upvotes: 0

Views: 261

Answers (1)

Mario Galic
Mario Galic

Reputation: 48410

Without the two imports we have to fully qualify the members we are accessing in Greeter and Printer singleton objects like so

class Greeter(message: String, printerActor: ActorRef) extends Actor {
  var greeting = ""

  def receive: PartialFunction[Any, Unit] = {
    case Greeter.WhoToGreet(who) =>
      greeting = message + ", " + who
    case Greeter.Greet           =>
      printerActor ! Printer.Greeting(greeting)
  }
}

so it is a bit more verbose at call-site

Greeter.WhoToGreet(who)
Greeter.Greet
Printer.Greeting(greeting)

as opposed to

import Greeter._ 
import Printer._    

WhoToGreet(who)
Greet
Greeting(greeting)

The notation import Greeter._ brings into scope all the members of the object Greeter as opposed to members of a package.

Upvotes: 5

Related Questions