diff --git a/docs/declaring_arguments.md b/docs/declaring_arguments.md index 911b44c..b12ecfe 100644 --- a/docs/declaring_arguments.md +++ b/docs/declaring_arguments.md @@ -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 diff --git a/library/src/commonMain/kotlin/net/sergeych/lyng/Arguments.kt b/library/src/commonMain/kotlin/net/sergeych/lyng/Arguments.kt index ee79626..6f804f5 100644 --- a/library/src/commonMain/kotlin/net/sergeych/lyng/Arguments.kt +++ b/library/src/commonMain/kotlin/net/sergeych/lyng/Arguments.kt @@ -8,8 +8,18 @@ suspend fun Collection.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") - for (subitem in value.list) list.add(Arguments.Info(subitem, x.pos)) + 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)) }