Command line arguments

## Command line arguments

Consider the following little script (triangle1.kts):

fun triangle(n: Int) {
for (i in 1 .. n) {
for (j in 1 .. i)
print("*")
println()
}
}

val size = 5
triangle(size)


As you can guess, it produces this output:

$kts triangle1.kts * ** *** **** *****$

I can change the size of the triangle by editing the script and changing the value of size. Wouldn't it be much nicer if I could provide the size of the triangle when I call the script?

Command line arguments make this possible. Every time Kotlin executes a script, it takes all the arguments on the command line and packs them inside a list named args (for "arguments"). So we can change our script as follows (triangle2.kts):

val size = args[0].toInt()
triangle(size)

And now we can run it as we like:
$kts triangle2.kts 3 * ** ***$ kts triangle2.kts 5
*
**
***
****
*****
$kts triangle2.kts 10 * ** *** **** ***** ****** ******* ******** ********* **********  You can use as many command line arguments as you want (of course they have to fit on your command line when you enter them...). A simple test script is (arguments.kts) as follows: for (s in args) println(s)  And you could use it like this: $ kts arguments.kts I love CS109!
I
love
CS109!
$kts arguments.kts CS109 is the best course at KAIST... CS109 is the best course at KAIST...$ kts arguments.kts
$kts arguments.kts 13 + 21 13 + 21  Note that the number of spaces between arguments doesn't matter—only the arguments themselves are passed inside args. Also notice that when I call the script without extra arguments, nothing is printed. That's because in this case args is a list of length zero, and so the for-loop does nothing. Going back to our triangle2.kts script, it's not perfect: $ kts triangle2.kts
java.lang.ArrayIndexOutOfBoundsException: 0
at Triangle2.<init>(triangle2.kts:9)


What happened? I forgot to provide the size of the triangle, and so accessing args[0] failed.

So we should add some error checking to our script. Here is a better version (triangle3.kts):

if (args.size == 1) {
val size = args[0].toInt()
triangle(size)
} else
println("Usage: kts triangle.kts <size>")

Now it behaves in a more civilized way:
\$ kts triangle3.kts
Usage: kts triangle3.kts <size>

The script is still not perfect, but we'll cover that later when we know more about exceptions.
 Command line arguments