https://kotlinlang.org logo
Title
d

Davide Giuseppe Farella

01/29/2019, 10:20 PM
Declaring
class MyClass {
    fun CoroutineScope.run() 
}
MyClass
become the context of
run()
, while
CoroutineScope
become the "owner". That makes sense... But what I want the opposite effect? Sometimes I use this pattern
class Mapper<E, P> {
    fun <T> invoke( block: Mapper.() -> T ): T
    fun E.toPojo(): P
    fun P.toEntity(): E
}
And makes sense that
Mapper
is the context for call
mapper { entity.toPojo() }
But back to the first example, doesn't make sense to call
launch {
    with( myObj ) { run() } 
}
I would simply call
launch {
    myObj.run()
}
Is that possibile?
Basically yes, you either do
with( myObj ) { run() }
, or you pass the scope as a parametr and do
myObj.run(scope)
.
@Allan Wang mentioned some alternatives, tho. With
cancellableCoroutine
or
yeld
. I'm curious to see some examples.
d

Davide Giuseppe Farella

01/29/2019, 10:55 PM
Ops 😅 I hoped in a fancier way to do that 😁
g

ghedeon

01/29/2019, 10:56 PM
aren't we all? :troll:
👍 1
it's all shine and roses when the caller is close to the fun definition. But if you start thinking of deeper callstack, through your domain, data layer... ugh. Let say you put
CoroutineScope
in all your public methods, later you refactor and realize that for a particular case
suspend
is enough and
scope
param is redundant? How many places do you need to change now? 🤔 What if you change your mind the next day?
d

Davide Giuseppe Farella

01/29/2019, 11:06 PM
Usually I use
suspend
everywhere, but in this case I don't care about the "lifecycle" of this function, I just care about results returned by `Channel`s
That's my use case
The best solution I found as now
suspend operator fun <T> MyClass.invoke( block: suspend MyClass.() -> T ) = block()
launch { myObj { doSmtng() } }
Basically the same pattern described for
Mapper
above 😔