Scala Command-Line Hacks

Alex Boisvert - 22 Apr 2013

Do you like command-line scripting and one-liners with Perl, Ruby and the like?

For instance, here's a Ruby one-liner that uppercases the input:

% echo matz | ruby -p -e '$_.tr! "a-z", "A-Z"'MATZ

You like that kind of stuff? Yes? Excellent! Then I offer you a hacking idea for Scala.

As you may know, Scala offers similar capability with the -e command-line option but it's fairly limited in its basic form because of the necessary boilerplate code to set up iteration over the standard input... it just begs for a simple HACK!

Using a simple bash wrapper,

#!/bin/bash
#
# Usage: scala-map MAP_CODE
#
code=$(cat<<END
scala.io.Source.stdin.getLines map { $@ } foreach println
END
)
scala -e "$code"

then we can express similar one-liners using Scala code and the standard library:

 

% ls | scala-map _.toUpperCase

# FOO
# BAR
# BAZ
# ...

% echo "foo bar baz" | scala-map '_.split(" ").mkString("-")'
# foo-bar-baz

Nifty, right? Here's another script template to fold over the standard input,

#!/bin/bash

#
# Usage: scala-fold INITIAL_VALUE FOLD_CODE
#
# where the following val's can be used in FOLD_CODE:
#
# `acc` is bound to the accumulator value
# `line` is bound to the current line
#


code=$(cat END
println(scala.io.Source.stdin.getLines.foldLeft($1) { case (acc, line) => $2 })
END
)
scala -e "$code"

Now if you wanted to calculate the sum of the second column of space-separated input, you'd write:

$ cat | scala-fold 0 'acc + (line.split(" ")(1).toInt)'foo 1bar 2baz 3
(CTRL-D)6You get the idea ... hopefully this inspires you to try a few things with Scala scripting templates!
comments powered by Disqus