Given a Map[String, Int] in Scala, I want to create a trait that allows me to add extra logic to the add and get methods. What would be the correct syntax for doing this? (Note: I also want to invoke the super method in each case)
I tried something like:
var mymap: Map[String, Int] with mytrait[String, Int] = Map[String, Int]()
trait mytrait[A, B] {
abstract override def +[ B1 >: B] (kv: (A, B1)) : Map[A, B1] = { /* ... */ }
}
But the interpreter complains so I’m obviously missing something syntactically, specifically with the use of the type parameters.
Many thanks for the help
To be more specific: What I have is a map already in place in my code, and so rather than rewrite large chunks of my program, I want to add logic to the + method and get method of the Map so that it does extra logic every time items are added to the map elsewhere in the program. Hence why I opted for a trait to add functionality to the map
Here is my code at present :
trait RegManager[A, B] extends scala.collection.Map[A, B] {
case class KeyAlreadyExistsException(e: String) extends Exception(e)
abstract override def + [B1 >: B] (kv: (A, B1)): scala.collection.Map[A, B1] = {
super.+[B1](kv)
}
abstract override def get(key: A): Option[B] = super.get(key)
abstract override def iterator: Iterator[(A, B)] = super.iterator
abstract override def -(key: A): scala.collection.Map[A, B] = super.-(key)
}
var regs = new scala.collection.Map[String, Int] with RegManager[String, Int]
Update:
In the end I opted for a wrapper style implementation (Decorator DP) which got the job done. I am only 6 months in to my Scala career so I might not have understood the capabilities of traits correctly yet?! Great language though!
either
MyTrait[A,B] extends Map[A,B]orMyTrait[A,B] {this: Map[A,B] => ...Sorry, in fact it is unlikely you can make that work this way.
First part of my answer was related to the fact that your declaration of MyTrait does not reference Map, so there is no chance that it could override the + of Map. You need something like
However that will not get you very far, for many reasons :
in the declaration
the value
Map[String, Int]()has type Map and is unrelated to your trait. Declaring the variablemymapof typeMap with mytraitwill not make it so. It will just prevent it to compile.MyTrait must appear in the creation of the map, not just in the type declaration of the variable. That would be something like
new Map[A,B] with MyTrait[A,B](note thenew).However,
Mapis a trait, not a concrete class, so you have to bring in some concrete implementation. Should you manage to do that, you then have to be careful that the new map returned by + has type MyTrait mixed in too (which of course your concrete implementation is unlikely to do). Otherwise, once you have added one element, you are back to a Map without MyTrait.