Friday, May 22, 2009

Wicked Cool Ruby Scripts are not so wicked cool

I got a review copy of Wicked Cool Ruby Scripts by Steve Pugh. I had my hopes up, as I quite enjoy reading cookbook-style books on programming - they are digestible in small pieces, what works great with my Internet-induced attention deficit, and they are mines of useful tidbits of programming knowledge.

Unfortunately Wicked Cool Ruby Scripts didn't do it for me. The subtitle says "Useful scripts that solve difficult problems", but most of the scripts were targeting trivial toy problems instead, like playing rock, paper, scissors with a computer (why would anybody do that), or reimplementing grep... not terribly useful. I'd say maybe 20% of the scripts do something useful that isn't a one-liner.

Now that on its own wouldn't be enough to give the book a bad review - I might have written a few Library-of-Congress-fuls of Ruby scripts already, so basics are obviously boring to me, but there are more beginners around than people like me, so beginner books are very useful to them. But there's a second problem that bothers me a lot - it's not said anywhere but the book is clearly targeted at Windows system administrators. The scripts instead of following Unix conventions like input from STDIN and arguments, output to STDOUT, errors to STDERR and so on, ask for all the input interactively or load it from predefined files, dump errors on STDOUT, and save output to predefined files.

For example here's a script which prints all IP addresses between a starting and ending one. They way it's implemented in the book is:

class IP # Code here is perfectly fineendprint "Input Starting IP Address"start_ip = gets.stripprint "Input Ending IP Address: "end_ip = gets.stripi = ="ips.txt", "w")ofile.puts i.succ! until i == end_ipofile.close

But that's horrible! This script is only useful for anything when manually operated. The entire point of scripts is that they can be building blocks of bigger scripts!

The proper way would be:

class IP # ...endraise "Usage: #{$0} start_ip end_ip" unless ARGV.size == 2start_ip, end_ip = *ARGVi = i.succ! until i == end_ip

That is - input from command line arguments, output to stdandard out. Unlike script in the book, this can be used as a building block for something bigger.

I'd say the book was a great idea, but a wasted opportunity. I'd only recommend it for beginner Windows administrators, for everybody else it's either too basic, or teaches some seriously bad practice