Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I overload parenthesis in Scala?

Tags:

scala

Trying to figure out out how to overload parenthesis on a class.

I have this code:

class App(values: Map[String,String])
{
  // do stuff
}

I would like to be able to access the values Map this way:

var a = new App(Map("1" -> "2"))
a("1") // same as a.values("1")

Is this possible?

like image 688
Joshua Avatar asked Aug 23 '10 20:08

Joshua


People also ask

Which function overloads the operator in Scala?

Operator Overloading in Scala Scala supports operator overloading, which means that the meaning of operators (such as * and + ) may be defined for arbitrary types. This code determines whether or not a complex number C is in the Mandelbrot Set.

Can you do += in Scala?

There are no ++ or -- operators in Scala (use += or -=) Second, Scala encourages the use of immutable values, and with immutable values you'll have no need for these operators.


4 Answers

You need to define an apply method.

class App(values: Map[String,String]) {
  def apply(x:String) = values(x)
  // ...
}
like image 51
sepp2k Avatar answered Oct 08 '22 13:10

sepp2k


For completeness, it should be said that your "apply" can take multiple values, and that "update" works as the dual of "apply", allowing "parentheses overloading" on the left-hand-side of assignments

Class PairMap[A, B, C]{
   val contents: mutable.Map[(A,B), C]  = new mutable.Map[(A, B), C]();
   def apply(a:A, b:B):C = contents.get((a, b))
   def update(a:A, b:B, c:C):Unit = contents.put((a, b), c)
}

val foo = new PairMap[String, Int, Int]()
foo("bar", 42) = 6
println(foo("bar", 42)) // prints 6

The primary value of all this is that it keeps people from suggesting extra syntax for things that had to be special-cased in earlier C-family languages (e.g. array element assignment and fetch). It's also handy for factory methods on companion objects. Other than that, care should be taken, as it's one of those things that can easily make your code too compact to actually be readable.

like image 40
Dave Griffith Avatar answered Oct 08 '22 13:10

Dave Griffith


As others have already noted, you want to overload apply:

class App(values: Map[String,String]) {
  def apply(s: String) = values(s)
}

While you're at it, you might want to overload the companion object apply also:

object App {
  def apply(m: Map[String,String]) = new App(m)
}

Then you can:

scala> App(Map("1" -> "2"))  // Didn't need to call new!
res0: App = App@5c66b06b

scala> res0("1")
res1: String = 2

though whether this is a benefit or a confusion will depend on what you're trying to do.

like image 5
Rex Kerr Avatar answered Oct 08 '22 14:10

Rex Kerr


I think it works using apply : How does Scala's apply() method magic work?

like image 4
Timo Westkämper Avatar answered Oct 08 '22 14:10

Timo Westkämper