Noel Yap
Noel Yap

Reputation: 19798

How to define Scala package object?

http://www.scala-lang.org/docu/files/packageobjects/packageobjects.html provides the following example:

// in file gardening/fruits/package.scala
package gardening
package object fruits {
  val planted = List(apple, plum, banana)               
  def showFruit(fruit: Fruit) {
    println(fruit.name +"s are "+ fruit.color)
  }
}

but http://www.scala-lang.org/docu/files/packageobjects/packageobjects_1.html has:

package gardening.fruits
object `package` { ... }

Since the latter example matches the filename with the object name and has the file in the package for which it's defining a package object, it looks more preferable. Is there a difference (other than stylistic)?

Upvotes: 1

Views: 979

Answers (1)

som-snytt
som-snytt

Reputation: 39587

The spec 9.3 says:

The standard naming convention is to place the definition above in a file named package.scala that’s located in the directory corresponding to package p.

That implies that the backticked form is not a standard convention.

I agree that there is not enough userland guidance, especially with respect to compile-time interactions.

The difference is that you can't name the default package.

object `package` {
  def f() = println("Hi")
}

object Foo extends App {
  f()
}

Edit: I have preferred to avoid backticks (because of the high danger of hitting tab or esc instead), but I just had a use case where I really want my code in one source file but I also prefer to avoid package nesting or relative packaging, hence backticking:

package com.github.maqicode.deprecator

object `package` {
  // crashes scalac, actually
  implicit class MaybeInt(val s: String) extends AnyVal {
    def toInt_? : Option[Int] = if (s.isEmpty) None else convert
    private def convert = try { Some(Integer.parseInt(s)) 
    } catch { case _: NumberFormatException => None }
  }
}

// lots of code, so avoid package deprecator { ... }

case class Version(major: Int, minor: Option[Int], point: Option[Int], descriptor: String)

object Version {
  val version = """(\d+)(?:\.(\d+))?(?:\.(\d+))?(.*)""".r
  def apply(descriptor: String): Version = {
    val version(major, minor, point, rest) = descriptor
    Version(major.toInt, minor.toInt_?, point.toInt_?, descriptor)
  }
}

As to the implicit question, who ever uses the default package in Scala: I saw it in test code.

And did you say "other than stylistic"? Hey, it's all about style.

Personally, I find the backticks hip but obscure. If I have to scratch my head an extra ten times every day, at the end of the year, I'll lose some hair.

OTOH, if I scratched my chin and went "Hmm" enough that I didn't have to shave, that would be OK.

This isn't one of those coursera questions, is it?

Upvotes: 2

Related Questions