diff options
author | Paul Phillips <paulp@improving.org> | 2010-11-01 16:27:13 +0000 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2010-11-01 16:27:13 +0000 |
commit | 9b54520a8c5a4f130a1fabbb0d0e7a3ec9022f41 (patch) | |
tree | 254c5a777abd099826873ac5ee686a5452370fdd /src/library/scala/Proxy.scala | |
parent | 1df37f476926ada63e223abcbe119147b6d693b3 (diff) | |
download | scala-9b54520a8c5a4f130a1fabbb0d0e7a3ec9022f41.tar.gz scala-9b54520a8c5a4f130a1fabbb0d0e7a3ec9022f41.tar.bz2 scala-9b54520a8c5a4f130a1fabbb0d0e7a3ec9022f41.zip |
Eliminated duplication among the Rich* wrappers...
Eliminated duplication among the Rich* wrappers, careful not to impact
performance on RichInt in particular. Attempted to make Proxy a little
bit typier. Proxy creates an asymmetric equals method by design so it's
unfixable in that regard, but achieved a minor miracle anyway by making
the Rich* wrappers behave symmetrically.
Note: said miracle involved having the wrappers extend ScalaNumber in
order to induce the special == semantics. This in turn led to implicit
conversion conflicts with the boxed types on methods like .intValue().
Resolved by moving the Rich* implicits into LowPriorityImplicits.
This of course also removed the intentional ambiguity which prevents
primitives from automatically becoming AnyRefs.
Solved THAT one by creating dedicated, laser-precise ambiguity creating
implicits in Predef which exclude only the AnyRef methods. Although
this is admittedly less than elegant, it is still better than it
was: this way it is direct and explicit rather than depending upon
the "implicit implicit conflict" where the barrier to promotion is
intermingled with the definitions of wrapper classes. (See the history
of BoxedUnit/RichUnit for a good example of why these concerns require
separation.)
It's all worth it:
assert(intWrapper(5) == 5)
assert(5 == intWrapper(5))
assert(5 == (5: java.lang.Integer))
assert((5: java.lang.Integer) == 5)
assert((5: java.lang.Integer) == intWrapper(5))
assert(intWrapper(5) == (5: java.lang.Integer))
Review by community.
Diffstat (limited to 'src/library/scala/Proxy.scala')
-rw-r--r-- | src/library/scala/Proxy.scala | 34 |
1 files changed, 24 insertions, 10 deletions
diff --git a/src/library/scala/Proxy.scala b/src/library/scala/Proxy.scala index feac5904a5..b7bf8eeef3 100644 --- a/src/library/scala/Proxy.scala +++ b/src/library/scala/Proxy.scala @@ -6,24 +6,38 @@ ** |/ ** \* */ - - package scala - /** This class implements a simple proxy that forwards all calls to - * methods of class <code>Any</code> to another object <code>self</code>. - * Please note that only those methods can be forwarded that are - * overridable and public. + * the public, non-final methods defined in class "Any" to another + * object self. Those methods are: + * + * def hashCode(): Int + * def equals(other: Any): Boolean + * def toString(): String + * + * Note: forwarding methods in this way will most likely create + * an asymmetric equals method, which is not generally recommended. * * @author Matthias Zenger * @version 1.0, 26/04/2004 */ trait Proxy { def self: Any - override def hashCode: Int = self.## - override def equals(that: Any): Boolean = - if(that == null) false - else that equals self + + override def hashCode: Int = self.hashCode + 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) + } override def toString: String = self.toString } + +object Proxy { + /** A proxy which exposes the type it is proxying for via a type parameter. + */ + trait Typed[T] extends Proxy { + def self: T + } +} |