splat any Iterable

This commit is contained in:
Sergey Chernov 2025-06-08 16:58:09 +04:00
parent 2b87845a40
commit 397dcaae92
2 changed files with 37 additions and 3 deletions

View File

@ -70,7 +70,31 @@ destructuring arrays when calling functions and lambdas:
fun getFirstAndLast(first, args..., last) {
[ first, last ]
}
getFirstAndLast( ...(1..10).toList() )
getFirstAndLast( ...(1..10) ) // see "splats" section below
>>> [1, 10]
# Splats
Ellipsis allows to convert argument lists to lists. The inversa algorithm that converts [List],
or whatever implementing [Iterable], is called _splats_. Here is how we use it:
fun testSplat(data...) {
println(data)
}
val array = [1,2,3]
testSplat("start", ...array, "end")
>>> ["start", 1, 2, 3, "end"]
>>> void
There could be any number of splats at any positions. You can splat any other [Iterable] type:
fun testSplat(data...) {
println(data)
}
val range = 1..3
testSplat("start", ...range, "end")
>>> ["start", 1, 2, 3, "end"]
>>> void
[tutorial]: tutorial.md

View File

@ -8,8 +8,18 @@ suspend fun Collection<ParsedArgument>.toArguments(context: Context): Arguments
for (x in this) {
val value = x.value.execute(context)
if (x.isSplat) {
(value as? ObjList) ?: context.raiseClassCastError("expected list of objects for splat argument")
when {
value is ObjList -> {
for (subitem in value.list) list.add(Arguments.Info(subitem, x.pos))
}
value.isInstanceOf(ObjIterable) -> {
val i = (value.invokeInstanceMethod(context, "toList") as ObjList).list
i.forEach { list.add(Arguments.Info(it, x.pos)) }
}
else -> context.raiseClassCastError("expected list of objects for splat argument")
}
} else
list.add(Arguments.Info(value, x.pos))
}