Declaring extension methods in a class object


#1

I'm trying to group a set of extension methods in a class object. I've can done this way:


import kotlin.template.*

class A {
  fun instanceName()=“A instance”

  
}
class B {
  class object {
  fun A.extendedName():String="According to B is "+instanceName()
  fun bName()=A().extendedName()
  }  
}

fun main(args : Array<String>) {
  
  
  println(A().instanceName())
  println(B.bName())
  //println(A().extendedName())  The compiler give an error here. extension is not directly visible
}

But it’s a bit ugly, because I have to provide a non-extension method (bName in the example) to give external visibility to extendedName().
Is this a compiler bug, or am I missing something?


#2

We decided for now to forbid imports for class object scope and this is the reason why extension function defined in it are not intended to be visible outside. It's expected that globaly used extension function should be defined at package level.


#3

Thank you Nikolay. Do you plan to allow for this in future releases?


#4

Probably yes if there will be enough convincing examples where it could be usefull. For now we are not sure that it's a good idea to declare extension function inside some class object and at the same time allow calling it with the syntax similar to package-level extension function. And will this ambiguity in syntax be a good trade-off for allowing to write functions with the knowledge of private static state (if there's no such dependency than function can be moved to the package-level).


#5

I try to explain my usage, I don't know if it's a convincing one. If you want, explain me how I can refactor it to some better form.

I whant to define a group of related web controllers in the same file, as I did here.
I define theme as RequestResponse extensions, to be able to call them without explicitly pass a RequestResponse argument,
as I did in App.kt.

For me it’s perfectly acceptable to define all my controllers methods at package level, but I want to have the possibility to import theme
as a group in some way.

I tryed to define all controllers in Layout.kt in package sites.welcome.controllers.quotes.
and then import them with
import sites.welcome.controllers.quotes.*

This work, but now I have to refer to them directly with the name, i.e. index()

If I have more controllers all with similar method names, I.e.
a file Quotes.kt with methods edit(), save() and another Company.kt with same names, I have to disambiguate
the methods when importing, one  by one.

What I really would want is the possibility to do an import this way:

import sites.welcome.controllers.quotes.*


and then refer to the methods this way:

quotes.index(), quotes.show() etc.

I don’t know, maybe the whole idea of doing controllers as method extension it’s not so good

Looking forward for your suggestion…


#6

You can import sites.welcome.controllers.* and then use quotes.foo() and quotes.bar()


#7

Hi Andrey. I tried to do this way, but the compiler does not resolve quotes.foo() and quotes.bar(); but I guess that if you are suggesting this, there is way to make it working, or you have made it working on new compiler versions.

I am now working on one of the TeamCity build of the compiler, but I never tried with this.
I will retry with this version and let you know if I’ll succed.


#8

If your foo() and bar() are extension functions, that won't work for now (will be supported later), but if they are normal functions, it should work


#9

Ah, ok I understood, effectively they are... So I'll just workaround by renaming imports until the fetaure will be available.