1

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?)

2 Answers 2

4

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Fascinating! This was more or less my approach, but it didn't work because I'd left the parens off of def apply(). It compiles, but the compiler then refuses to accept the symbol help().
1

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)

2 Comments

Thanks! You've also answered another question that's been simmering in the back of my brain... I tend to avoid parens in 0-parameter functions because I find less noise makes the code easier to read. (I know many people develop conventions about when to use them, and what it means.) But I've been wondering if there's any case where they are necessary - and you've found it! Thanks again!
@LeoOrientis The general rule is to use () when calling a method that changes state but omit them for pure functional accessors. E.g. x.close() but x.isOpen. So this use of help() is not really in line with this rule, and using x.help.usage would be a better pattern.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.