16

I recently started to work on play & reactive mongo. Referred the reactive mongo documentation to create a SimpleAlbum. When I run the play app I am getting an error like "Implicit modifier cannot be used for top-level objects". Why am I getting this? Help me in resolving the issue. Thanks

package models

import org.joda.time.DateTime
import reactivemongo.bson._


case class SimpleAlbum(
                    title: String,
                    releaseYear: Int,
                    hiddenTrack: Option[String],
                    allMusicRating: Option[Double])

implicit object SimpleAlbumWriter extends BSONDocumentWriter[SimpleAlbum] {
def write(album: SimpleAlbum): BSONDocument = BSONDocument(
   "title" -> album.title,
   "releaseYear" -> album.releaseYear,
   "hiddenTrack" -> album.hiddenTrack,
   "allMusicRating" -> album.allMusicRating)
}

implicit object SimpleAlbumReader extends BSONDocumentReader[SimpleAlbum] {
def read(doc: BSONDocument): SimpleAlbum = {
SimpleAlbum(
  doc.getAs[String]("title").get,
  doc.getAs[Int]("releaseYear").get,
  doc.getAs[String]("hiddenTrack"),
  doc.getAs[Double]("allMusicRating"))
 }
}
cchantep
  • 9,118
  • 3
  • 30
  • 41
Kaushik
  • 1,271
  • 2
  • 18
  • 35

2 Answers2

25

implicit cannot be used at the package level. You need to put your implicit objects inside another object that you can then import where you need the implicits, e.g.:

object MyImplicits {

   implicit object SimpleAlbumWriter ....

   implicit object SimpleAlbumReader ....
}

and then where you need access to the implicits just put

import MyImplicits._

as part of the package imports.

EDIT: As @m-z points out, using the package object, you can and define implicits at the package level like this:

package models

package object Implicits {

   implicit object SimpleAlbumWriter ....

   implicit object SimpleAlbumReader ....
}

which imports in the same way:

import models.Implicits._
Arne Claassen
  • 14,088
  • 5
  • 67
  • 106
  • 2
    One could also use a `package object`. – Michael Zajac Apr 30 '15 at 17:25
  • I was wondering about that. Wasn't sure if the top level constraint was enforced at the package object level – Arne Claassen Apr 30 '15 at 17:28
  • Yes, it's a special case where the object name can collide with the package path, and everything within the `package object` is in the scope of that package. eg., `package object models { val a = 1 }` makes `a` available throughout `package models`. – Michael Zajac Apr 30 '15 at 17:36
0

Implicit class need to add into the object:

object StudentTest {
 implicit class stringUtils(myString:String){
 def scalaWordCount(): Map[String, Int] ={
  val split=myString.split("\\s+")
  val grouped=split.groupBy(word=>word)
  val counterPerKey=grouped.mapValues(group=>group.length)
  counterPerKey
}

}

Shyam Gupta
  • 489
  • 4
  • 8