7

I must be missing something silly here. I have this:

case class Color(val rgb:Int) {
   private val c = rgb - 0xff000000
   val r = (c & 0xff0000) >> 16
   val g = (c & 0x00ff00) >> 8
   val b = (c & 0x0000ff)
}

case object Red extends Color(0xffff0000)
case object Green extends Color(0xff00ff00)
case object Blue extends Color(0xff0000ff)

Then I expect this to print true:

val c = Color(0xff00ff00)
println(c == Green)

Why doesn't it??

Germán
  • 4,525
  • 3
  • 31
  • 37
  • 2
    Another tip: the `val` in the argument to `Color` is redundant, since `Color` is a case class. It's sufficient to say: `case class Color(rgb: Int)` – Kipton Barros Aug 23 '11 at 21:12
  • 1
    Yes, that was a late addition as I was trying to make it work as I expected; now that you mention it, I remember it isn't needed. – Germán Aug 24 '11 at 14:06

3 Answers3

13

Case classes (or objects) inheriting from case classes is a bad practice, and is illegal as of Scala 2.9.1. Use object instead of case object to define Red, Green and Blue.

Kipton Barros
  • 21,002
  • 4
  • 67
  • 80
4e6
  • 10,696
  • 4
  • 52
  • 62
  • 3
    case object create `equals`, `hashcode` and `apply/unapply`. Why is it bad practice? – Amir Raminfar Aug 23 '11 at 20:17
  • 2
    @Amir Raminfar: No, it actually doesn't in this case, because the methods already exist on `Color` and `case` only creates these methods if they aren't already overridden. @4e6: it doesn't matter if you use `object` or `case object` if you are still inheriting from a case class! – Alexey Romanov Aug 23 '11 at 20:22
  • Ah you mean subclassing a case class. I think you should change the wording because it sounds like you are saying using `case objects` is bad in general. – Amir Raminfar Aug 23 '11 at 20:24
  • 1
    @Alexey Romanov , the issue is case-to-case inheritence. It's ok if a non case object inherits from a case class. I updated the answer to clarify this. – Kipton Barros Aug 23 '11 at 20:26
  • Thanks, @kipton. That's what I meant. – 4e6 Aug 23 '11 at 20:27
  • At any rate, I'd define `Red`, `Green` and `Blue` as `val`s in `object Color`. – Alexey Romanov Aug 23 '11 at 20:34
  • Maybe somebody else wrote the class color, and you want to define some not so popular color like petrol or elephant. – user unknown Aug 24 '11 at 01:02
  • Is it better to have a case class at the root of the inheritance or at the leaf? (assuming that I only have one case class and all others normal classes). – Jus12 Sep 10 '12 at 15:58
0

I think it was a relevant question: "Why case object and case class it extends are not equal".

Using Scala 2.12.2

I added following lines to your example and and now object is equal to the class instance.

object Black extends Color(0x00000000)
val black1 = Color(0x00000000)
black1 == Black

res1: Boolean = true

Donald Duck
  • 476
  • 3
  • 12
0

Why should that be true? Green is a companion object, c is an instance. They aren't equal.

Michael Lorton
  • 43,060
  • 26
  • 103
  • 144
  • It's a bug with case-to-case inheritance, which is now illegal. The code works when the case modifier is removed from the objects, because the definition of `==` on case classes checks equality of the arguments (here, `rgb`). By the way, `Green` is not a companion object to class `Color`. A companion object needs to have the same name as the trait/class, and (I think) needs to be defined in the same file. More info on why companion objects are useful: http://stackoverflow.com/questions/609744/what-is-the-rationale-behind-having-companion-objects-in-scala – Kipton Barros Aug 23 '11 at 21:09