Last active
September 8, 2022 07:56
-
-
Save elizarov/fab9b26a89d34a47e64a85ef7f4a0db3 to your computer and use it in GitHub Desktop.
Aspect operators
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Aspect interface for combinator | |
interface Aspect { | |
operator fun <R> invoke(block: () -> R): R | |
} | |
// Aspect combinator | |
operator fun Aspect.plus(other: Aspect) = object : Aspect { | |
override fun <R> invoke(block: () -> R): R = | |
this@plus { | |
other { | |
block() | |
} | |
} | |
} | |
// inline version of logged aspect | |
inline fun <R> logged(block: () -> R): R { | |
println("Logged before") | |
return try { | |
block() | |
} finally { | |
println("Logged after") | |
} | |
} | |
// functional version of logged aspect for combinator | |
val logged = object : Aspect { | |
override fun <R> invoke(block: () -> R): R = logged(block) | |
} | |
// inline version of transactional aspect | |
inline fun <R> transactional(block: () -> R): R { | |
println("Transactional before") | |
return try { | |
block() | |
} finally { | |
println("Transactional after") | |
} | |
} | |
// functional version of transactional aspect for combinator | |
val transactional = object : Aspect { | |
override fun <R> invoke(block: () -> R): R { | |
return transactional(block) | |
} | |
} | |
// --- test code -- | |
fun testLogged() = logged { | |
println("testLogged") | |
} | |
fun testTransactional() = transactional { | |
println("testTransactional") | |
} | |
fun testBoth() = (logged + transactional) { | |
println("testBoth") | |
} | |
fun main() { | |
testLogged() | |
testTransactional() | |
testBoth() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment