Leo Orientis
Leo Orientis

Reputation: 1061

Scala: Use function and inner object with the same name

For the convenience of my users, I'd like to design an interface like the following:

class MyApplication {
  def help = "usage..."

  object help {
    def topics : List[String] = List( ... )
  }
}

But of course, the collision of the function and the object called help make this impossible.

Is there any way to do this in Scala? eg, Have one behaviour if the user calls help with nothing following, and another behaviour if they call help.topics?

(If not, what is the idiomatic Scala way to do something similar?)

Upvotes: 1

Views: 489

Answers (2)

Tim
Tim

Reputation: 27356

It is not possible to have a class where .help returns a String while .help.topics returns a List[String]. But here is an option for your application that uses a helper class. This would be more applicable if you have a range of classes each with their own help information.

abstract class Help {
  val usage: String
  val topics: List[String]

  def apply() = usage
  override def toString = usage
}

class MyApplication {
  object help extends Help {
    val usage = "usage"
    val topics = List("Topic1", "Topic2")
  }
}

val a = new MyApplication

println(a.help)
println(a.help())
println(a.help.topics)

Upvotes: 1

Antot
Antot

Reputation: 3964

Yes, this is possible to achieve if def help is transformed into apply inside object help:

class MyApplication {

  object help {

    def topics : List[String] = List("a", "b")

    def apply(): String = "usage..."
  }
}

Now, it compiles and the following calls are possible:

val myApp = new MyApplication()

myApp.help()
myApp.help.topics

However, there are still the parentheses in .help() to use, otherwise myApp.help remains a function reference.

Upvotes: 4

Related Questions