Skip to content

Commit 722776f

Browse files
committed
Backport scala.util.chaining
1 parent 7d1f7aa commit 722776f

File tree

2 files changed

+105
-0
lines changed

2 files changed

+105
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/*
2+
* Scala (https://www.scala-lang.org)
3+
*
4+
* Copyright EPFL and Lightbend, Inc.
5+
*
6+
* Licensed under Apache License 2.0
7+
* (http://www.apache.org/licenses/LICENSE-2.0).
8+
*
9+
* See the NOTICE file distributed with this work for
10+
* additional information regarding copyright ownership.
11+
*/
12+
13+
package scala.util
14+
15+
trait ChainingSyntax {
16+
@`inline` implicit final def scalaUtilChainingOps[A](a: A): ChainingOps[A] = new ChainingOps(a)
17+
}
18+
19+
/**
20+
* Adds chaining methods `tap` and `pipe` to every type. See [[ChainingOps]].
21+
*/
22+
object chaining extends ChainingSyntax
23+
24+
/** Adds chaining methods `tap` and `pipe` to every type.
25+
*/
26+
final class ChainingOps[A](private val self: A) extends AnyVal {
27+
28+
/** Applies `f` to the value for its side effects, and returns the original value.
29+
*
30+
* {{{
31+
* scala> import scala.util.chaining._
32+
*
33+
* scala> val xs = List(1, 2, 3).tap(ys => println("debug " + ys.toString))
34+
* debug List(1, 2, 3)
35+
* xs: List[Int] = List(1, 2, 3)
36+
* }}}
37+
*
38+
* @param f the function to apply to the value.
39+
* @tparam U the result type of the function `f`.
40+
* @return the original value `self`.
41+
*/
42+
def tap[U](f: A => U): A = {
43+
f(self)
44+
self
45+
}
46+
47+
/** Converts the value by applying the function `f`.
48+
*
49+
* {{{
50+
* scala> import scala.util.chaining._
51+
*
52+
* scala> val times6 = (_: Int) * 6
53+
* times6: Int => Int = \$\$Lambda\$2023/975629453@17143b3b
54+
*
55+
* scala> val i = (1 - 2 - 3).pipe(times6).pipe(scala.math.abs)
56+
* i: Int = 24
57+
* }}}
58+
*
59+
* Note: `(1 - 2 - 3).pipe(times6)` may have a small amount of overhead at
60+
* runtime compared to the equivalent `{ val temp = 1 - 2 - 3; times6(temp) }`.
61+
*
62+
* @param f the function to apply to the value.
63+
* @tparam B the result type of the function `f`.
64+
* @return a new value resulting from applying the given function
65+
* `f` to this value.
66+
*/
67+
def pipe[B](f: A => B): B = f(self)
68+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package scala.util
2+
3+
import org.junit.Assert._
4+
import org.junit.Test
5+
6+
//import scala.tools.reflect.ToolBoxError
7+
//import scala.tools.testkit.RunTesting
8+
9+
class ChainingOpsTest {
10+
import scala.util.chaining._
11+
12+
@Test
13+
def testAnyTap(): Unit = {
14+
var x: Int = 0
15+
val result = List(1, 2, 3)
16+
.tap(xs => x = xs.head)
17+
18+
assertEquals(1, x)
19+
assertEquals(List(1, 2, 3), result)
20+
}
21+
22+
@Test def testAnyValTap(): Unit = assertEquals(42.tap(x => x), 42)
23+
24+
@Test
25+
def testAnyPipe(): Unit = {
26+
val times6 = (_: Int) * 6
27+
val result = (1 - 2 - 3)
28+
.pipe(times6)
29+
.pipe(scala.math.abs)
30+
31+
assertEquals(24, result)
32+
}
33+
34+
// @Test(expected = classOf[ToolBoxError])
35+
// def testNoSelf(): Unit =
36+
// runner.run("import scala.util.chaining._; Nil.self")
37+
}

0 commit comments

Comments
 (0)