Idiomatic way to access instance members from suspending function

If you have a suspending function you need to wrap it in a coroutineScope generally. If there’s an alternative I’m not sure what it is. However because that effectively makes the function body a lambda it seems like it loses access to the class instance’s this scope. Kotlin’s scoped this can’t access it by the function name.

Here’s a contrived example of the problem:

class Worker {
	fun next(): Step? {
		// contrived example
		return if(someArrayList.size > 0) someArrayList.removeAt(0) else null
	}

	suspend fun executeAll() = coroutineScope {
		while(this.isActive) {
			// This is an error here! @executeAll isn't accessible by scope
			val step = this@executeAll.next()

			if(step == null)
				break

			// step.execute() is a suspending function on an interface
			step.execute()

			// cleanup work for each step omitted
		}
	}
}

But if we define the same function as an extension instead:

class Worker {
	fun next(): Step? {
		// contrived example
		return if(someArrayList.size > 0) someArrayList.removeAt(0) else null
	}
}

suspend fun executeAll() = coroutineScope {
	while(this.isActive) {
		// as an extension function we *can* use scoped this on @executeAll
		val step = this@executeAll.next()

		if(step == null)
			break

		// step.execute() is a suspending function on an interface
		step.execute()

		// cleanup work for each step omitted
	}
}

It works fine, however you have to explicitly import the extension function. You also can’t define the extension in the class body, it has to be separated.

Is there a more idiomatic way to do this?

Thanks!

Inside member functions the label is not the name of the function but of the class, so you have to use this@Worker.

Can’t believe I didn’t try that. Thank you very much.