多くの場合、次のような関数があります。
{
val x = foo;
bar(x);
x
}
たとえば、bar
はしばしば のようなものLog.debug
です。
それを実行するためのより短く、慣用的な方法はありますか? たとえば、次のような組み込み関数
def act[A](value: A, f: A => Any): A = { f(value); value }
私はただ書くことができるようにact(foo, bar _)
。
書かれたとおりに関数を使用するact
ことは、私にとって完全に慣用的なようです。組み込みの方法はわかりませんが、この種のものをどこでも使用する「コモンズ」または「ユーティリティ」プロジェクトに入れるだけです。
bar 関数が通常同じである場合 (Log.debug など)、そのための特定のラッパー関数を作成することもできます。例えば:
def withDebug[A](prefix: String)(value: A)(implicit logger: Logger): A = {
logger.debug(prefix + value)
value
}
次のように使用できます。
implicit val loggerI = logger
def actExample() {
// original method
val c = act(2 + 2, logger.debug)
// a little cleaner?
val d = withDebug("The sum is: ") {
2 + 2
}
}
または、さらに多くの構文シュガーについては、次のようにします。
object Tap {
implicit def toTap[A](value: A): Tap[A] = new Tap(value)
}
class Tap[A](value: A) {
def tap(f: A => Any): A = {
f(value)
value
}
def report(prefix: String)(implicit logger: Logger): A = {
logger.debug(prefix + value)
value
}
}
object TapExample extends Logging {
import Tap._
implicit val loggerI = logger
val c = 2 + 2 tap { x => logger.debug("The sum is: " + x) }
val d = 2 + 2 report "The sum is: "
assert(d == 4)
}
Wheretap
は任意の関数を取り、report
ロガーをラップするだけです。もちろん、他の一般的に使用されるタップをTap
クラスに追加することもできます。
Scala にはすでに構文的に重いバージョンが含まれていることに注意してください。
foo match { case x => bar(x); x }
しかし、短いバージョン ( tap
Ruby で同じ名前を使用することをお勧めします) を作成すると、利点が得られます。