rrva
09/15/2020, 2:30 PMfun computeNewValue(msg: String, oldValue: String): String {
return try {
println(msg)
computeNewValue()
} catch(e: RuntimeException) {
oldValue
}
}
fun main() {
val foo = Foo()
foo.someProperty = computeNewValue("Computing foo", foo.someProperty)
}
nanodeath
09/15/2020, 2:31 PMnanodeath
09/15/2020, 2:31 PMrrva
09/15/2020, 2:34 PMprivate inline fun <reified T> read(key: String, oldValue: T):
then I have to write
foo.property1 = read("property1", foo.property1)
foo.property2 = read("property2", foo.property2)
Maybe using KMutableProperty1
I could do something to the signature of read()
https://kotlinlang.org/docs/tutorials/kotlin-for-py/member-references-and-reflection.htmlnanodeath
09/15/2020, 2:36 PMnanodeath
09/15/2020, 2:37 PMHans Ellegard
09/15/2020, 2:40 PMfoo.someProperty
once, it would be akin to augmented assignment. nothing wrong with that in general, but it would be yet another step away from immutability. i feel it would fit better in a language where references to mutable variables occur naturally, e.g. c++. for languages such as kotlin or rust, i would try to do something elserrva
09/15/2020, 2:44 PMprivate inline fun <reified T> read(prop: KMutableProperty0<T>): T {
return read(prop::name.get(), prop.get())
}
rrva
09/15/2020, 2:45 PMprivate inline fun <reified T> read(key: String, oldValue: T): T {
rrva
09/15/2020, 2:46 PMfoo.someProperty = read(foo::someProperty)
nanodeath
09/15/2020, 2:47 PMrrva
09/15/2020, 2:48 PMrrva
09/15/2020, 2:50 PMrrva
09/15/2020, 2:50 PMTobias Berger
09/15/2020, 3:12 PMfun <T> KMutableProperty0<T>.refreshValue(msg: String) {
try {
println(msg)
set(computeNewValue())
} catch (ignored: RuntimeException) {}
}
fun main() {
val foo = Foo()
foo::someProperty.refreshValue("Computing foo")
}
Tobias Berger
09/15/2020, 3:15 PMnull
(or at least do so in the wrapper function) and then only assign it if the value is not null
(computeNewValue()?.let { foo.someProperty = it }
)nanodeath
09/15/2020, 3:17 PMvetoable
might help https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.properties/-delegates/vetoable.htmlTobias Berger
09/15/2020, 3:21 PMnanodeath
09/15/2020, 3:22 PMrrva
09/15/2020, 3:26 PMprivate inline fun <reified T> update(prop: KMutableProperty0<T>) {
val newValue = read(prop::name.get(), prop.get())
prop.set(newValue)
}
private inline fun <reified T> read(key: String, oldValue: T): T {
Which I call using
update(foo::someProperty)
This is bad I guess since it messes with “find usages”. The let
solution is perhaps cleanest in that senseNir
09/15/2020, 3:28 PMNir
09/15/2020, 3:42 PMNir
09/15/2020, 3:42 PM%=
, if you only define %
then when you do x %= foo
it will turn that into x = x % foo
Nir
09/15/2020, 3:42 PMTobias Berger
09/15/2020, 3:45 PMNir
09/15/2020, 3:48 PMNir
09/15/2020, 3:48 PMNir
09/15/2020, 3:48 PMTobias Berger
09/15/2020, 3:50 PMbasePath / "myDir" / filename
)Nir
09/15/2020, 3:54 PMNir
09/15/2020, 3:54 PMNir
09/15/2020, 3:55 PMNir
09/15/2020, 3:55 PMrrva
09/15/2020, 7:26 PMlet
solution fails because it cannot infer the type…
I had
private inline fun <reified T> read(key: String): T
But of course I cannot write
read("foo")?.let { repository.foo = it }
Nir
09/15/2020, 7:31 PMNir
09/15/2020, 7:31 PMNir
09/15/2020, 7:34 PMNir
09/15/2020, 7:34 PMprivate inline fun <reified T> read(key: String, setter: (T) -> Unit)
Nir
09/15/2020, 7:35 PMread("foo") { repository.foo = it}
Nir
09/15/2020, 7:35 PMrrva
09/15/2020, 7:35 PMprivate inline fun <reified T> read(prop: KMutableProperty0<T>): T? {
return read(prop::name.get())
}
private inline fun <reified T> read(key: String): T? { ... }
read(repository::someProperty)?.let { repository.someProperty = it }
Nir
09/15/2020, 7:35 PMread
would internally only call setter
if it got a new valueNir
09/15/2020, 7:36 PMrrva
09/15/2020, 7:36 PMNir
09/15/2020, 7:36 PMNir
09/15/2020, 7:39 PMrrva
09/15/2020, 7:42 PMNir
09/15/2020, 7:42 PMNir
09/15/2020, 7:42 PMNir
09/15/2020, 7:42 PMrepository.someProperty = it
is enough to deduce the type of it
rrva
09/15/2020, 7:43 PMNir
09/15/2020, 7:44 PMNir
09/15/2020, 7:45 PMit
must be the same typeNir
09/15/2020, 7:45 PMval x = list(); x.push(5)
and it will go "backwards" and deduce that x must have been list<int>Nir
09/15/2020, 7:46 PMit
must be whatever type, to make the body of the lambda work. ANd then, go further backwards to deduce the correct types for read
Nir
09/15/2020, 7:47 PMNir
09/15/2020, 7:48 PM%=
Nir
09/15/2020, 7:48 PMNir
09/15/2020, 7:48 PMrepository.someProperty %= read("hello")
Nir
09/15/2020, 7:48 PM%=
, *=
, etc, doesn't matter which one