alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Scala example source code file (Equality.scala)

This example Scala source code file (Equality.scala) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Scala tags/keywords

any, any, anyref, anyref, atom, boolean, boolean, equality, equality, node, nodeseq, seq, string

The Scala Equality.scala source code

/*                     __                                               *\
**     ________ ___   / /  ___     Scala API                            **
**    / __/ __// _ | / /  / _ |    (c) 2003-2011, LAMP/EPFL             **
**  __\ \/ /__/ __ |/ /__/ __ |    http://scala-lang.org/               **
** /____/\___/_/ |_/____/_/ | |                                         **
**                          |/                                          **
\*                                                                      */

package scala.xml

/** In an attempt to contain the damage being inflicted on
 *  consistency by the ad hoc equals methods spread around
 *  xml, the logic is centralized and all the xml classes
 *  go through the xml.Equality trait.  There are two forms
 *  of xml comparison.
 *
 *  1) def strict_==(other: xml.Equality)
 *
 *  This one tries to honor the little things like symmetry
 *  and hashCode contracts.  The equals method routes all
 *  comparisons through this.
 *
 *  2) xml_==(other: Any)
 *
 *  This one picks up where strict_== leaves off.  It might
 *  declare any two things equal.
 *
 *  As things stood, the logic not only made a mockery of
 *  the collections equals contract, but also laid waste to
 *  that of case classes.
 *
 *  Among the obstacles to sanity are/were:
 *
 *    Node extends NodeSeq extends Seq[Node]
 *    MetaData extends Iterable[MetaData]
 *    The hacky "Group" xml node which throws exceptions
 *      with wild abandon, so don't get too close
 *    Rampant asymmetry and impossible hashCodes
 *    Most classes claiming to be equal to "String" if
 *      some specific stringification of it was the same.
 *      String was never going to return the favor.
 */

object Equality {
  def asRef(x: Any): AnyRef = x.asInstanceOf[AnyRef]
  
  /** Note - these functions assume strict equality has already failed.
   */
  def compareBlithely(x1: AnyRef, x2: String): Boolean = x1 match {
    case x: Atom[_]   => x.data == x2
    case x: NodeSeq   => x.text == x2
    case _            => false
  }
  def compareBlithely(x1: AnyRef, x2: Node): Boolean = x1 match {
    case x: NodeSeq if x.length == 1  => x2 == x(0)
    case _                            => false
  }
  def compareBlithely(x1: AnyRef, x2: AnyRef): Boolean = {
    if (x1 == null || x2 == null)
      return (x1 eq x2)

    x2 match {
      case s: String  => compareBlithely(x1, s)
      case n: Node    => compareBlithely(x1, n)
      case _          => false
    }
  }
}
import Equality._

private[xml]
trait Equality extends scala.Equals {
  def basisForHashCode: Seq[Any]
  def strict_==(other: Equality): Boolean
  def strict_!=(other: Equality) = !strict_==(other)

  /** We insist we're only equal to other xml.Equality implementors,
   *  which heads off a lot of inconsistency up front.
   */
  override def canEqual(other: Any): Boolean = other match {
    case x: Equality    => true
    case _              => false
  }

  /** It's be nice to make these final, but there are probably
   *  people out there subclassing the XML types, especially when
   *  it comes to equals.  However WE at least can pretend they
   *  are final since clearly individual classes cannot be trusted
   *  to maintain a semblance of order.
   */
  override def hashCode()         = basisForHashCode.##
  override def equals(other: Any) = doComparison(other, false)
  final def xml_==(other: Any)    = doComparison(other, true)
  final def xml_!=(other: Any)    = !xml_==(other)

  /** The "blithe" parameter expresses the caller's unconcerned attitude
   *  regarding the usual constraints on equals.  The method is thereby
   *  given carte blanche to declare any two things equal.
   */
  private def doComparison(other: Any, blithe: Boolean) = {
    val strictlyEqual = other match {
      case x: AnyRef if this eq x => true
      case x: Equality            => (x canEqual this) && (this strict_== x)
      case _                      => false
    }
    
    strictlyEqual || (blithe && compareBlithely(this, asRef(other)))
  }
}

Other Scala examples (source code examples)

Here is a short list of links related to this Scala Equality.scala source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.