1

I am a newbie to scala. So far i learned that, object in scala is singleton and if we declare case object, then override and hashcode default implementations are also added.

Just wondering to find any simple practical example, where we can fit case object.


Edit 1:

@Aivean :-

But without declaring object as case, below code also works fine :-

object ScalaPractice {

  def main(args: Array[String]): Unit = {
    val trade1 = Trade(EUR)
    trade1.currency match{
      case EUR | USD => println("trade possiblein this currency : " + trade1.currency)
      case _ => println("trade not possible")
    }
  }
}

case class Trade(val currency : Currency){

}

sealed trait Currency { def name: String }
object EUR extends Currency { val name = "EUR" }
object USD extends Currency { val name = "USD" }

Why it is required to add case ?


Edit 2:

@dwickern

As @dwickern quoted :-

Converting your object to a case object gives you:

  1. A slightly nicer default toString implementation
  2. The case object automatically implements Serializable. This can be important, for example when passing these objects as messages via akka remoting
  3. You also get default equals, hashCode and scala.Product implementations just like a case class but these really don't really matter

Is there any official documentation for this on scala website, scal docs, etc.. (specially for the third point, that is in bold italics)

mogli
  • 1,549
  • 4
  • 29
  • 57
  • http://www.scala-lang.org/files/archive/spec/2.11/05-classes-and-objects.html – ayvango Aug 01 '15 at 00:08
  • For "enum" case the only practical difference is automatic `@serializable` addition. Mostly it's just consistency. Scala's case classes are often described as "enums with properties". They are completely defined by their fields. So it makes sense that case class without parameter should be singleton — case object. – Aivean Aug 01 '15 at 01:02
  • @ayvango : i am not able to find any description about "case object" on the link that you have provided. I t will be great, if you can also provide section details on the page :) – mogli Aug 01 '15 at 03:25
  • It says that object is equivalent to class. So you just look for case modifier for class – ayvango Aug 01 '15 at 07:00
  • i read the documentation, but not able to figure out that "default equals, hashCode and Scala.Product implementations" that is provided by Scala compiler for a case object does not really matter". But those default implementations matter a lot if "case" is used with a "class". Just wondering, if generated implementation really don't matter when "case" is used with "object", then, why compiler is generating those implementations. – mogli Aug 02 '15 at 06:53

3 Answers3

2

Converting your object to a case object gives you:

  1. A slightly nicer default toString implementation
  2. The case object automatically implements Serializable. This can be important, for example when passing these objects as messages via akka remoting

For example:

case object USD
object EUR

println(USD) // USD
println(EUR) // testapp$EUR$@edf4efb

val oos = new ObjectOutputStream(new ByteArrayOutputStream())
oos.writeObject(USD)
oos.writeObject(EUR) // java.io.NotSerializableException

You also get default equals, hashCode and scala.Product implementations just like a case class but these really don't really matter

dwickern
  • 3,519
  • 1
  • 14
  • 21
0

One of good examples is with actor model. Here case object can represent a message to send to an actor:

case object Start

someActorRef ! Start

Here this object doesn't contain any data it just serves the protocol of messaging - indicates that actor should execute some start logic.

Another example if you writing API for remote control, your API can take as arguments commands like: turn left, turn right, etc. It can be good idea to implement these commands as case objects - they doesn't have any state:

case object Left
case object Right
case object Up
case object Down
ka4eli
  • 5,294
  • 3
  • 23
  • 43
  • cant we just send an object. isit really required to send a case object ? – mogli Jul 31 '15 at 21:47
  • yes, we can, no we are not required. But we have to instantiate regular object, like `new Object()` which is just more verbose. – ka4eli Jul 31 '15 at 21:53
  • it will be great if you can provide example for initialization of object and case object. AFAIK, there is no need to use new to initialize object. – mogli Jul 31 '15 at 21:58
  • every time you create a new object, `new` keyword is used under the hood except the case when you do it via reflection. – ka4eli Jul 31 '15 at 22:05
  • I was trying to understand, why it is required to add case to LEFT, RIGHT, UP, DOWN objects. – mogli Jul 31 '15 at 22:10
  • it's not required. One of the advantages it gives you is that it makes them singletons by default and you don't have to instantiate them - they are already objects. – ka4eli Jul 31 '15 at 22:19
  • 1
    This doesn't make sense. If they weren't `case object`s and just regular `object`s, they would still be `object`s and thus still be singletons and still wouldn't need to be instantiated. – Jörg W Mittag Jul 31 '15 at 22:58
0
  1. Case objects are handy when used as enums (example from here):
sealed trait Currency { def name: String }
case object EUR extends Currency { val name = "EUR" }
case object USD extends Currency { val name = "USD" }
  1. Case objects can be used along with case classes in order to provide immutable implementation for some corner cases.

Check the Nil from scala.collection.immutable:

case object Nil extends List[Nothing]
Community
  • 1
  • 1
Aivean
  • 10,692
  • 25
  • 39