is there a trick to overcome clashing function sig...
# getting-started
e
is there a trick to overcome clashing function signatures with different returns values?
Copy code
fun TfFile.cert_request(configure: CertRequest.() -> Unit): CertRequest

fun TfFile.cert_request(configure: CertRequest.() -> Unit): PropertyDelegateProvider<Any?, ReadOnlyProperty<Any?, CertRequest>>
@JvmName
works only for case like
List<String
and
List<Int
and
@OverloadResolutionByLambdaReturnType
only with lambdas returning different values
j
Compiler problems aside, how would you expect people to understand which function is called?
e
Copy code
cert_request { }
            val a by cert_request { }
if I make use of delegation or not
j
In the case where you don't use it with
by
, how do you know which one it is?
e
ok
y
How about implementing an
operator fun CertRequest.provideDelegate
? Could that do the trick?
e
I played with the
provideDelegate
, but I didn't have any luck 😕
y
Is there a specific reason why it didn't work? Whenever a property is delegated to a
CertRequest
the `provideDelegate`method should be called automatically, allowing you to do whatever you want. In fact, you can take the current method which returns a Delegate provider and instead make it return its delegate in
CertRequest.provideDelegate
You might need to make
TfFile
a context receiver I guess, but it should work I believe.
e
ok, let's give it a try, why
CertRequest.provideDelegate
? I need as owner
TfFile
(I have to add this
CertRequest
instance to a list inside
TfFile
)
y
Well, is there different logic between a normal CertRequest and one that's inside a property delegate?
e
no
y
If there is a difference, then you need this:
Copy code
context(TfFile)
operator fun CertRequest.provideDelegate(...): ReadOnlyProperty<...> {
    this@TfFile.removeCert(this)
    this@TfFile.addCert(generateNewCert())
    return ReadOnlyProperty<...> {...}
}
Okay then, you don't even need a provide delegate. You can simply have this:
Copy code
operator fun CertRequest.getValue(...): CertRequest = this
In other words, CertRequest is used as a delegate that just returns itself! That then allows you to have only one
TfFile.cert_request
and still have it be used as a delegate when needed
e
I'd like to use the variable name though
val a by cert_request
, in this case
a
and save it inside
CertRequest
thta's why I was using
provideDelegate
pattern
y
Is CertRequest modifiable after creation? If so:
Copy code
operator fun CertRequest.provideDelegate(...): CertRequest= this.apply {
    this.myName = property.name
}
operator fun CertRequest.getValue(...): CertRequest = this
e
I can make it modifiable
y
If you wanna keep it not modifiable though, it is a bit more awkward but you can do something like this:
Copy code
context(TfFile)
operator fun CertRequest.provideDelegate(...): CertRequest = this.copy(name = property.name).also {
    this@TfFile.removeCertificate(this)
    this@TfFile.addCertificate(it)
} 
operator fun CertRequest.getValue(...): CertRequest = this
But yes I'd suggest to just make it modifiable to make it easier
e
so, I have the following, how the
by cert_request
is supposed to call
CertRequest.provideDelegate
? Because it's always being redirected to
TfFile.cert_request
did you mean
val a by CertRequest()
? It works quite good in this way indeed
y
No I meant exactly what is in the gist. Does it not work as expected?
e
wait
no you are right, it works, now I get what you meant: so first
TfFile.cert_request
is called, and then
CertRequest.provideDelegate
that's a sweet trick, thanks Youssef metal
y
Yep exactly! No problem at all, glad I could help!