This was the tip of the week in the October 26, 2021 Ruby Weekly Newsletter.


In a recent Tip of the Week, we learned about the -e and -c flags we can use when running Ruby from the comand line. Ruby has many more flags we can use as well! (ruby --help shows us the full list of flags.) Of note today, the -n and -p flags both wrap scripts in loops.

-n adds a while gets ... end loop around our script. gets reads user input and stores it in a $_. So adding a while gets loop around our script allows us to continually read in user input. Without the -n flag, if we were testing snippets of code which respond to user input, we might keep re-running them on different manual test cases. This while loop with the -n flag can be specifically useful for testing snippets of code without needing to re-run the snippets.

The syntax to use with the -n flag if using a Ruby script is ruby -n file.rb, but for a one liner we can continue to use -e as we explored last week. For example:

$ ruby -ne 'puts "You said #{$_}"'
Hello there!
You said Hello there!
something else
You said something else

(Note that the Hello there! and something else are user input, while the interleaving statements are printed output. You could also pipe in other data to be processed by this loop, such as with ls | ruby -ne 'puts "You said #{$_}"' which would then run the code for each file returned by ls.)

As always, we can exit this while loop using control-D.

Taking the -n flag one step further, the -p flag will wrap a ruby file in a while gets loop and also print the user input itself. So using the same small example as above, we can do the following:

$ ruby -pe 'puts "You said #{$_}"'
Hello there!
You said Hello there!
Hello there!
something else
You said something else
something else

We input Hello there! and something else, Ruby executes our script, and then also prints our input again. This can be more handy, perhaps, when you want to make quick transformations over incoming data and then have it output again without using something like puts yourself.

For example:

$ echo "hello world" | ruby -pe '$_.upcase!'
HELLO WORLD

Try this with the piped ls idea from above to see what happens!