Implementing attribute methods with additional implicit parameters

I want the object to implement the Iterable attribute and pass an additional implicit parameter to the implemented method:

 object MyRepository extends Iterable[Something] { def iterator(implict entityManager: EntityManager): Iterator[Something] = ... } 

Obviously, this does not work, because the iterator method does not have an implicit parameter and, therefore, is not implemented as described above.

An example of use is the map method, which I want to apply to the values ​​of the repository:

  def get = Action { Transaction { implicit EntityManager => val result = MyRepository.map(s => s ...) } } 

Is there a way to implement an Iterable trait and capture an implicit pramameter?

+6
source share
1 answer

Given that Iterable.iterator does not have this implicit in its signature, you cannot expect to be able to implement this method when adding this implicit: it will be a different method (in particular, another overload).

However, if MyRepository was a class, not an object, you could capture the implicit in the class constructor. And if you want to keep the same usage style (as in MyRepository.map{ ... } , and not new MyRepository.map{ ... } ), then you can do an implicit conversion from an object to a class.

Here is an example:

 object MyRepository { class MyRepositoryIterable(implicit entityManager: EntityManager) extends Iterable[Something] { def iterator: Iterator[Something] = ??? } implicit def toIterable(rep: MyRepository.type)(implicit entityManager: EntityManager): MyRepositoryIterable = new MyRepositoryIterable } 

Now, when you do MyRepository.map(...) , what happens is that the object is implicitly converted to an instance of MyRepositoryIterable , which captures the implicit value of EntityManager . MyRepositoryIterable is a class that actually implements Iterable .

+9
source

All Articles