Case classes and Proxy behaviour in Scala 2.9
On migrating our code to Scala 2.9 we've found large swathes of it that didn't work and failed silently. We tracked it down to case classes that extend Proxy not being equal. In our code we don't extend Proxy directly, we just extend classes in libraries that extend Proxy.
Any help would be greatly appreciated.
In 2.8
scala> case class Test(a:String) extends Proxy {
| def self = a
| }
defined class Test
scala>开发者_JAVA百科;
scala> val label = new Test("bla")
label: Test = bla
scala> println(label == label) // this is TRUE
true
scala> println(label == "bla")
true
In 2.9
scala> case class Test(a:String) extends Proxy {
| def self = a
| }
defined class Test
scala>
scala> val label = new Test("bla")
label: Test = bla
scala> println(label == label) // this is now FALSE
false
scala> println(label == "bla")
true
Update
I think this can only be a bug in Scala 2.9. Otherwise if you have a case class that extends any other class you have to investigate that base class's hierarchy to make sure at no point is it extending Proxy. We won't be able to do this in our code, we'll just be able to fix the more obvious bugs. If this is intended behaviour then a compiler warning is a must. Does that sound about right?
Update
Also being discussed on the scala mailing list.
Update
I've filed a bug
In 2.9 they changed the equals method from:
override def equals(that: Any): Boolean =
if(that == null) false
else that equals self
to
override def equals(that: Any): Boolean = that match {
case null => false
case x: Equals => (x canEqual self) && (x equals self)
case x => (x equals self)
}
x: Equals doesn't equal self for some reason.
You can override the equals method to fix it.
This will solve your problem
case class Test(a: String) extends Proxy {
def self = a
def canEqual(that: Any) = that match {
case that: String => true
case _ => false
}
}
So why don't you overwrite the equals method? That should solve the problem.
精彩评论