Skip to content

Instantly share code, notes, and snippets.

@elizarov
Last active September 8, 2022 07:56
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save elizarov/fab9b26a89d34a47e64a85ef7f4a0db3 to your computer and use it in GitHub Desktop.
Save elizarov/fab9b26a89d34a47e64a85ef7f4a0db3 to your computer and use it in GitHub Desktop.
Aspect operators
// 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