diff options
author | Paul Phillips <paulp@improving.org> | 2011-02-19 19:59:40 +0000 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2011-02-19 19:59:40 +0000 |
commit | 68d13416b50acb1779a3befe817fb2a7eabe9f14 (patch) | |
tree | 7c4ba0d3b702b6bc05edebd91a43a681a13d2110 | |
parent | e91c0e25f1095e77b8dcc8342893462d072a35e9 (diff) | |
download | scala-68d13416b50acb1779a3befe817fb2a7eabe9f14.tar.gz scala-68d13416b50acb1779a3befe817fb2a7eabe9f14.tar.bz2 scala-68d13416b50acb1779a3befe817fb2a7eabe9f14.zip |
Rediscovering that transpose sometimes throws a...
Rediscovering that transpose sometimes throws an exception on irregular
lists and sometimes returns an irregular result (depending on whether
the first collection is the longest or not) indicated that this needs a
better resolution than the status quo. Determination: as long as we're
throwing an exception on any invalid input, we should throw an exception
on all invalid input, so that's what it does now. I postpone any attempt
to offer a variation accepting a "hole value". Closes #3597, review by
community.
-rw-r--r-- | src/library/scala/collection/generic/GenericTraversableTemplate.scala | 12 | ||||
-rw-r--r-- | test/files/run/transpose.scala | 12 |
2 files changed, 23 insertions, 1 deletions
diff --git a/src/library/scala/collection/generic/GenericTraversableTemplate.scala b/src/library/scala/collection/generic/GenericTraversableTemplate.scala index 6a1bff6cec..d6f01718ff 100644 --- a/src/library/scala/collection/generic/GenericTraversableTemplate.scala +++ b/src/library/scala/collection/generic/GenericTraversableTemplate.scala @@ -12,6 +12,7 @@ package scala.collection package generic import mutable.Builder +import annotation.migration import annotation.unchecked.uncheckedVariance /** A template class for companion objects of ``regular`` collection classes @@ -136,18 +137,27 @@ trait GenericTraversableTemplate[+A, +CC[X] <: Traversable[X]] extends HasNewBui * element type of this $coll is a `Traversable`. * @return a two-dimensional $coll of ${coll}s which has as ''n''th row * the ''n''th column of this $coll. + * @throws `IllegalArgumentException` if all collections in this $coll + * are not of the same size. */ + @migration(2, 9, "As of 2.9, transpose throws an exception if collections are not uniformly sized.") def transpose[B](implicit asTraversable: A => /*<:<!!!*/ TraversableOnce[B]): CC[CC[B] @uncheckedVariance] = { if (isEmpty) return genericBuilder[CC[B]].result - val bs: IndexedSeq[Builder[B, CC[B]]] = IndexedSeq.fill(asTraversable(head).size)(genericBuilder[B]) + def fail = throw new IllegalArgumentException("transpose requires all collections have the same size") + + val headSize = asTraversable(head).size + val bs: IndexedSeq[Builder[B, CC[B]]] = IndexedSeq.fill(headSize)(genericBuilder[B]) for (xs <- this) { var i = 0 for (x <- asTraversable(xs)) { + if (i >= headSize) fail bs(i) += x i += 1 } + if (i != headSize) + fail } val bb = genericBuilder[CC[B]] for (b <- bs) bb += b.result diff --git a/test/files/run/transpose.scala b/test/files/run/transpose.scala new file mode 100644 index 0000000000..2761a24ff5 --- /dev/null +++ b/test/files/run/transpose.scala @@ -0,0 +1,12 @@ +object Test { + def wrap[T >: Null](body: => T) = + try body + catch { case _: IllegalArgumentException => null } + + def main(args: Array[String]): Unit = { + assert(wrap(Nil.transpose) == Nil) + assert(wrap(List(List(1, 2), List(1)).transpose) == null) + assert(wrap(List(List(1), List(1, 2)).transpose) == null) + assert(wrap(List(List(1, 2), List(1, 2)).transpose) == List(List(1, 1), List(2, 2))) + } +} |