Contextual extension methods


#1

Can I somehow define a “contextual” extension method as following example ?
For case SomeClass is final and not part of my source code ?

class SomeClass {
    val value = true
    fun Boolean.toInt() = if (this == true) 1 else 0
}

fun func() {
    //true.toInt()//doesn't compile
    SomeClass().apply {
        value.toInt()//works fine
    }
}

Any ideas how to do it ?


#2

The Boolean.toInt() in your example becomes a member of SomeClass; it receives a SomeClass instance, can access its private members, etc. You cannot add a member to a class that is not part of your source code.


#3

Hi Yole,

thank you for your reply. I think you missed my point. I understand that adding a member to some non-own class is not possible. But this is purely about extension methods

class SomeClass {
    val value = true
    fun Boolean.toInt() = if (this == true) 1 else 0
}

fun Boolean.toInt2() = if (this == true) 1 else 0

fun func() {
    //true.toInt()//doesn't compile
    SomeClass().apply {
        value.toInt()//works fine
    }
}

As you can see in this example. Extension function toInt2() is visible everywhere.
My point is to declare toInt2() somehow with same scope as toInt() has. So it would be accessible only in
SomeClass().apply { ... }

Thing is, for some extension functions they don’t make much sense in global scope as they are tied to some specific type in terms of usage/meaning. So i was wondering if I could declare extension function scoped only to some someObject.apply {}

I believe technically it should be feasible as it’s nothing else than static java method with argument of extended type. In this case it would have 2 arguments, one the extended type and 2nd the object what I’m trying to scope with…

Thanks for any thoughts…


#4

What you seem to want is the ability to have multiple receivers on a (extension) function. Currently this is not possible even though there appear to be (limited) use cases for it. Note that even the member extension functions can be quite awkward to use.