improved lazy delegate; added with(newThis) {} to stdlib
This commit is contained in:
parent
f792c73b8f
commit
41a3617850
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
### Unreleased
|
### Unreleased
|
||||||
|
|
||||||
|
- Language: stdlib improvements
|
||||||
|
- Added `with(self, block)` function to `root.lyng` which executes a block with `this` set to the provided object.
|
||||||
- Language: Abstract Classes and Interfaces
|
- Language: Abstract Classes and Interfaces
|
||||||
- Support for `abstract` modifier on classes, methods, and variables.
|
- Support for `abstract` modifier on classes, methods, and variables.
|
||||||
- Introduced `interface` as a synonym for `abstract class`, supporting full state (constructors, fields, `init` blocks) and implementation by parts via MI.
|
- Introduced `interface` as a synonym for `abstract class`, supporting full state (constructors, fields, `init` blocks) and implementation by parts via MI.
|
||||||
|
|||||||
@ -298,6 +298,16 @@ It works much like `also`, but is executed in the context of the source object:
|
|||||||
assertEquals(p, Point(2,3))
|
assertEquals(p, Point(2,3))
|
||||||
>>> void
|
>>> void
|
||||||
|
|
||||||
|
## with
|
||||||
|
|
||||||
|
Sets `this` to the first argument and executes the block. Returns the value returned by the block:
|
||||||
|
|
||||||
|
class Point(x,y)
|
||||||
|
val p = Point(1,2)
|
||||||
|
val sum = with(p) { x + y }
|
||||||
|
assertEquals(3, sum)
|
||||||
|
>>> void
|
||||||
|
|
||||||
## run
|
## run
|
||||||
|
|
||||||
Executes a block after it returning the value passed by the block. for example, can be used with elvis operator:
|
Executes a block after it returning the value passed by the block. for example, can be used with elvis operator:
|
||||||
@ -1519,7 +1529,7 @@ See [math functions](math.md). Other general purpose functions are:
|
|||||||
| flow {} | create flow sequence, see [parallelism] |
|
| flow {} | create flow sequence, see [parallelism] |
|
||||||
| delay, launch, yield | see [parallelism] |
|
| delay, launch, yield | see [parallelism] |
|
||||||
| cached(builder) | [Lazy evaluation with `cached`](#lazy-evaluation-with-cached) |
|
| cached(builder) | [Lazy evaluation with `cached`](#lazy-evaluation-with-cached) |
|
||||||
| let, also, apply, run | see above, flow controls |
|
| let, also, apply, run, with | see above, flow controls |
|
||||||
|
|
||||||
(1)
|
(1)
|
||||||
: `fn` is optional lambda returning string message to add to exception string.
|
: `fn` is optional lambda returning string message to add to exception string.
|
||||||
|
|||||||
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
import com.codingfeline.buildkonfig.compiler.FieldSpec.Type.STRING
|
import com.codingfeline.buildkonfig.compiler.FieldSpec.Type.STRING
|
||||||
import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
|
import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
|
||||||
|
import org.jetbrains.kotlin.gradle.ExperimentalWasmDsl
|
||||||
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
||||||
|
|
||||||
group = "net.sergeych"
|
group = "net.sergeych"
|
||||||
@ -65,11 +66,11 @@ kotlin {
|
|||||||
browser()
|
browser()
|
||||||
nodejs()
|
nodejs()
|
||||||
}
|
}
|
||||||
// @OptIn(ExperimentalWasmDsl::class)
|
@OptIn(ExperimentalWasmDsl::class)
|
||||||
// wasmJs() {
|
wasmJs() {
|
||||||
// browser()
|
browser()
|
||||||
// nodejs()
|
nodejs()
|
||||||
// }
|
}
|
||||||
|
|
||||||
// Suppress Beta warning for expect/actual classes across all targets
|
// Suppress Beta warning for expect/actual classes across all targets
|
||||||
targets.configureEach {
|
targets.configureEach {
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2025 Sergey S. Chernov real.sergeych@gmail.com
|
* Copyright 2026 Sergey S. Chernov real.sergeych@gmail.com
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -113,4 +113,22 @@ class StdlibTest {
|
|||||||
assertEquals(5, (1..10).toList().count { it % 2 == 1 } )
|
assertEquals(5, (1..10).toList().count { it % 2 == 1 } )
|
||||||
""")
|
""")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testWith() = runTest {
|
||||||
|
eval("""
|
||||||
|
class Person(val name, var age)
|
||||||
|
val p = Person("Alice", 30)
|
||||||
|
|
||||||
|
val result = with(p) {
|
||||||
|
assertEquals("Alice", name)
|
||||||
|
assertEquals(30, age)
|
||||||
|
age = 31
|
||||||
|
"done"
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEquals("done", result)
|
||||||
|
assertEquals(31, p.age)
|
||||||
|
""".trimIndent())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -287,4 +287,40 @@ class DelegationTest {
|
|||||||
""".trimIndent())
|
""".trimIndent())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testThisInLazy() = runTest {
|
||||||
|
eval("""
|
||||||
|
class A {
|
||||||
|
val numbers = [1,2,3]
|
||||||
|
val tags by lazy { this.numbers }
|
||||||
|
}
|
||||||
|
class B {
|
||||||
|
val a by lazy { A() }
|
||||||
|
val test by lazy { a.tags + [4] }
|
||||||
|
}
|
||||||
|
assertEquals( [1,2,3], A().tags)
|
||||||
|
assertEquals( [1,2,3,4], B().test)
|
||||||
|
""")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testScopeInLazy() = runTest {
|
||||||
|
val s1 = Script.newScope()
|
||||||
|
s1.eval("""
|
||||||
|
class A {
|
||||||
|
val tags by lazy { GLOBAL_NUMBERS }
|
||||||
|
}
|
||||||
|
""".trimIndent())
|
||||||
|
// on the same scope, it will see my GLOBAL_NUMBERS:
|
||||||
|
s1.eval("""
|
||||||
|
val GLOBAL_NUMBERS = [1,2,3]
|
||||||
|
class B {
|
||||||
|
val a by lazy { A() }
|
||||||
|
val test by lazy { a.tags + [4] }
|
||||||
|
}
|
||||||
|
assertEquals( [1,2,3], A().tags)
|
||||||
|
assertEquals( [1,2,3,4], B().test)
|
||||||
|
""")
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -310,6 +310,16 @@ interface Delegate {
|
|||||||
fun bind(name, access, thisRef) = this
|
fun bind(name, access, thisRef) = this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Executes the block with `this` set to self and
|
||||||
|
returns what the block returns.
|
||||||
|
*/
|
||||||
|
fun with(self, block) {
|
||||||
|
var result = Unset
|
||||||
|
self.apply { result = block() }
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Standard implementation of a lazy-initialized property delegate.
|
Standard implementation of a lazy-initialized property delegate.
|
||||||
The provided creator lambda is called once on the first access to compute the value.
|
The provided creator lambda is called once on the first access to compute the value.
|
||||||
@ -325,7 +335,7 @@ class lazy(creatorParam) : Delegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun getValue(thisRef, name) {
|
override fun getValue(thisRef, name) {
|
||||||
if (value == Unset) value = creator()
|
if (value == Unset) value = with(thisRef,creator)
|
||||||
value
|
value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user