« Return to Thread: equals in case class does not seem to be working...
Let me expand a bit on this. Case classes serve a specific purpose, which is to implement algebraic types in an object-oriented way. To do this, a bunch of methods are automatically created, and just a little bit of magic compiler glue is applied. But for those methods to work, some assumptions have to be made, and making parts of the case class mutable violate those assumptions. See here, for instance:scala> case class T(var i: Int) // Our mutable case class
defined class Tscala> T(0) // One instance of it
res4: T = T(0)scala> res4.hashCode // It's hashcode
res5: Int = 3444scala> scala.collection.immutable.HashMap(res4 -> 'a) // Let's use it as a key
res9: scala.collection.immutable.HashMap[T,Symbol] = Map(T(0) -> 'a)scala> res9(res4) // Can we retrieve it?
res10: Symbol = 'ascala> res4.hashCode // Check the hashCode
res11: Int = 3444scala> res4.i = 1 // Let's mutate itscala> res4.hashCode // How's the hashCode now?
res12: Int = 3445scala> res9(res4) // Can we retrieve it now?
java.util.NoSuchElementException: key not found: T(1)
at scala.collection.generic.MapTemplate$class.default(MapTemplate.scala:177)
at scala.collection.immutable.HashMap.default(HashMap.scala:30)
at scala.collection.generic.MapTemplate$class.apply(MapTemplate.scala:92)
at scala.collection.immutable.HashMap.apply(HashMap.scala:30)
at .<init>(<console>:9)
at .<clinit>(<console>)
a...
scala> res9(T(0)) // Well, we changed T(0) into a T(1), so let's retrieve a T(0)
java.util.NoSuchElementException: key not found: T(0)
at scala.collection.generic.MapTemplate$class.default(MapTemplate.scala:177)
at scala.collection.immutable.HashMap.default(HashMap.scala:30)
at scala.collection.generic.MapTemplate$class.apply(MapTemplate.scala:92)
at scala.collection.immutable.HashMap.apply(HashMap.scala:30)
at .<init>(<console>:9)
at .<clinit>(<console>)
a...
scala> T(0) // That didn't work. Let's make a new T(0)
res15: T = T(0)scala> res15.hashCode // Check hashCode...
res16: Int = 3444scala> res9(res15) // Can we get it?
java.util.NoSuchElementException: key not found: T(0)
at scala.collection.generic.MapTemplate$class.default(MapTemplate.scala:177)
at scala.collection.immutable.HashMap.default(HashMap.scala:30)
at scala.collection.generic.MapTemplate$class.apply(MapTemplate.scala:92)
at scala.collection.immutable.HashMap.apply(HashMap.scala:30)
at .<init>(<console>:10)
at .<clinit>(<console>)
...
scala> res9.keys foreach println // What _are_ the keys?
<console>:9: warning: method keys in trait MapTemplate is deprecated: use `keysIterator' instead
res9.keys foreach println
^
T(1)scala>
On Wed, Jul 8, 2009 at 12:17 PM, Daniel Sobral <dcsobral@...> wrote:
Why did you expect this to work? Case classes are supposed to be immutable.--
On Tue, Jul 7, 2009 at 10:39 PM, Alexandre <alexmsmartins@...> wrote:
Hi to you all
First of all I'm a less than a year scala hobbyist (e. g. user) and
this is my first post to this list. So bare with me. :)
I was trying to do unit testing and I thought that using
assertEquals() in Junit 4 with objects from the same case class with
exactly the same content wold cut it. Yet, I run into some troubles
and ended up doing this small snippet in the scala shell that shows me
it does not work.
Am I doing anything wrong or is this to be expected?
If it is to be expected could you explain/point to some reading that
makes it clear why.
Thanks in advance
Alexandre Martins
------------------------------------------------------------------------------------------
scala> import scala.xml.Node
import scala.xml.Node
scala> import scala.xml.Elem
import scala.xml.Elem
scala> import scala.reflect.BeanProperty
import scala.reflect.BeanProperty
scala> import scala.reflect.BeanProperty
import scala.reflect.BeanProperty
scala> import java.util.Date
import java.util.Date
scala> import scala.reflect.BeanInfo
import scala.reflect.BeanInfo
scala> /**
| * Represents a user of WikiModels
| */
scala> @BeanInfo
| case class User(usrName:String,
| pssword:String,
| frstName:String,
| lstName:String,
| mail:String ) extends DataModel {
|
| var userName = usrName
| var password = pssword
| var firstName = frstName
| var lastName = lstName
| var emailAddress = mail
|
| def this() = {
| this("","","","","")
| }
|
| /**
| * generates a XML representation of the user, excluding password
| * @return the XML representing the user
| */
| def toXML:Node =
| <user>
| <username>{userName}</username>
| <!--<password>{password}</password>-->
| <firstName>{firstName}</firstName>
| <lastName>{lastName}</lastName>
| <email>{emailAddress}</email>
| </user>
|
| def extractXML(xml:Node):Unit = {
| xml match {
| case <username>{contents}</username> =>
this.userName = contents.text
| case <firstName>{contents}</firstName> =>
this.firstName = contents.text
| case <lastName>{contents}</lastName> =>
this.lastName = contents.text
| case <email>{contents}</email> => this.emailAddress
= contents.text
| case <user>{c @ _ *}</user> => for (val child <- c)
extractXML(child)
| case _ => { }
| }
| }
| }
defined class User
scala> var u = User("alex","alexp","Alexandre",
"Martins","alexmsmartins@...")
u: User = User(alex,alexp,Alexandre,Martins,alexmsmartins@...)
scala> var d = new User()
d: User = User(,,,,)
scala> u == d
res2: Boolean = false
scala> u
res3: User = User(alex,alexp,Alexandre,Martins,alexmsmartins@...)
scala> d
res4: User = User(,,,,)
scala> d.extractXML( u.toXML)
scala> d.password = u.password
scala> d.password
res18: String = alexpscala> d
res7: User = User(,,,,)
scala> d.toXML == u.toXML
res8: Boolean = true
scala> d == u
res9: Boolean = false
Daniel C. Sobral
Something I learned in academia: there are three kinds of academic reviews: review by name, review by reference and review by value.
--
Daniel C. Sobral
Something I learned in academia: there are three kinds of academic reviews: review by name, review by reference and review by value.
« Return to Thread: equals in case class does not seem to be working...
| Free embeddable forum powered by Nabble | Forum Help |