Extension methods at runtime


#1

I was looking at the wasabi framework, and noticed some interesting usage of extension functions:

val handlerExtension : RouteHandler.() -> Unit = handler
val routeHandler = RouteHandler(request!!, response)
routeHandler.handlerExtension()

This appears to assign a function to RouteHandler, and then calls the function with a context of a new RouteHandler. Is this thread safe? If two requests are happening at the same time, wouldn't it be possible for this extension to get changed out from under the object? Perhaps I'm just a little confused as to how this is supposed to work.


#2

OK, in looking at it more, I think I understand it, though I'm not sure it's documented anywhere?

What’s happening is that it’s creating an extension function that is local to the block. This line:

val handlerExtension: RouteHandler.()->Unit = handler

Adds a new extension function that is callable only from the local scope. Whereas most extension functions are referred to via their full package name (imported as necessary), this is referenced locally. As such, there’s no thread issues at all; the function is like a local variable, except that it’s using the execution context of the object that it’s being called with.

Regardless, this is probably something worth documenting in the extension functions part of the wiki.


#3

It is not "like a local variable", it is a local variable that holds an object of type "extension function". Incidentally, you can define a proper extension funciton i na local scope:

fun foo(bar: Bar) {   fun Bar.baz() {...}

  bar.baz()
}