Package object warning?

452 views
Skip to first unread message

Rex Kerr

unread,
May 2, 2012, 6:43:14 PM5/2/12
to scala-user
I was trying out 2.10 M3 and got a huge number of warnings about not defining objects inside package objects.

How is one now supposed to conveniently create a single namespace that contains an important implicit conversion (i.e. what is the enrich-my-library pattern)?

I can of course put inside one file

package xyz {
  class MyUnit { def done = true }
}

package object xyz {
  implicit def enrich_unit(u: Unit) = new MyUnit
}

but it ends up a horrible mess when one has dozens or hundreds of these things.

What is wrong with putting everything inside a package object, anyway?  You can put stuff in an object without it scolding you.

  --Rex

Arya Irani

unread,
May 3, 2012, 2:07:21 PM5/3/12
to Rex Kerr, scala-user
I tried it with implicit classes, and got the same warnings:

package object xyz {
  implicit class MyUnit(u:Unit) { def done = true }
}
package abc {
  import xyz.MyUnit
  object Foo extends App {
    println(().done)
  }
}

scalac that ^^:

test2.scala:2: warning: it is not recommended to define classes/objects inside of package objects.
If possible, define class MyUnit in package xyz instead.
  implicit class MyUnit(u:Unit) { def done = true }
                 ^
one warning found 

If implicit classes have to be inside an object, it seems like the package object would be a reasonable place for them...  Perhaps more convenient would be if implicit classes could be defined at the top level, and the implicit conversion was automatically put into a package object, such that it would be imported with the class.  e.g.,

package xyz {
  implicit class MyUnit(u:Unit) { def done = true }
}
package abc {
  import xyz.MyUnit
  object Foo extends App {
    println(().done)
  }
}

being transformed into:

package xyz {
  class MyUnit(u:Unit) { def done = true }
}
package object xyz {
  implicit def MyUnit(u:Unit): MyUnit = new MyUnit(u)
}
package abc {
  import xyz.MyUnit
  object Foo extends App {
    println(().done)
  }
}

instead of 

test2.scala:2: error: `implicit' modifier cannot be used for top-level objects
  implicit class MyUnit(u:Unit) { def done = true }
                 ^
one error found
 

?

-Arya
Reply all
Reply to author
Forward
0 new messages