Tuesday, May 17, 2011

Book Review: The Facets of Ruby: Learn to Program: Second Edition

First, let me be frank. I’ve had an on and off relationship with programming over the years, somewhat akin to my relationship with the Japanese language. Hang on, this is not an irrelevant comparison :). I love the Japanese language, and I’ve even sat down to learn some of the language structure, how to write kana, etc. but I’m hampered by the fact that I don’t really have anyone close enough to me that I can really immerse myself in speaking or writing the language. Thus, while I love watching Anime in its original language and can understand a lot of what’s happening by context and repetition, I wouldn’t dream of saying I’m a Japanese language expert, because I’ve never had, or spent, enough time to learn it and practice it in a meaningful way.

Programming for me has been equally challenging.  I’ve taken many classes over the years, even getting a Certificate in UNIX Programming back in the mid 90s (focusing on C and C++). Still, I never did enough in my testing job to require much programming beyond shell scripts, thus the need for the skill would come and go. Same with other languages I’d focused on (Java, Perl, etc.). I learned enough to be pedestrian and get some important things done, but I never really made it a habit to program in them every day.

Thus, while I often joke that I can ask a lot of the right questions, and I can read code and understand it, it’s about at the level I understand Japanese. With great deliberation and care, I can tease out what’s happening and comment on it, but I’m nowhere near conversant enough to quickly and effectively write it on my own from scratch.

With my new job, I have had to make the realization that automated testing has to be part of my reality. It’s what we do here, and if any additional scripts are to be made, it’s up to me to make them. We are a Ruby on Rails shop, therefore, it’s time to learn some Ruby. Unfortunately, most books start off with the idea that you are already expert or polished in another language. I decided, this time, I’d take Ruby on Soup to Nuts, and approach it as though it were a totally new endeavor.

Learn to Program, Second Edition (The Facets of Ruby Series) is part of the Practical Programmer’s arsenal of Ruby books, and the key reason I chose it was to see if I, a neophyte to Ruby, could get into the flow of the book and “unlearn” a few things while I “learn” the Ruby language itself. To that end, Chris Pine has set up something fun, quirky and entertaining while seeking to give some insights to someone looking to learn how to program.

Chris makes no assumptions about the level of understanding the programmer has (or doesn’t have). He starts from the beginning without being patronizing. This book itself grew out of a much tweaked and worked over tutorial for Ruby (in fact it was the tutorial and its approach that made me interested in learning more about this particular book).

So, does Chris deliver on the promise to teach Ruby to a “beginner” in a manner that will actually “stick”?


Chris starts out the book describing what many of us already know... computers are inherently stupid, but they are very fast. Humans are inherently brilliant, but they are generally slow. Putting the two together, you can accomplish amazing things, but first, you have to get down to understanding just how stupid computers are. They don’t do what we ask them to, they do what we tell them to, and we have to appreciate how that telling gets accomplished. Computers are very literal machines, and as such, we have to create programs that are also very literal. Ruby allows for a way to do that in an abstracted way that is elegant, clean, and does not waste effort for needless repetition. Unlike languages like Java or C/C++, many of the declarations and setup requirements for things like methods and system calls are handled internal to the language. What would take five lines in Java (printing a simple text string) is done in one line with Ruby. Chris shares the oft-repeated DRY philosophy of programming, which means “Don’t Repeat Yourself” when you program.

Getting Started

A little time to get the user set up and understand what they need to be productive and able to write programs with Ruby. For me, this meant how to set up Ruby on Mac OS X and download TextMate (just to simplify things; I have an extensive IDE in RubyMine, but I often find the IDE to be distracting, so I went through the book with TextMate and a UNIX prompt).


Basic examples dealing with numbers and text strings are placed in front of the would be programmer and the ubiquitous puts statement certainly gets a workout here :). The examples are simple enough to be a quick win for the beginner but not so simple as to be seen as almost irrelevant.


Along with numbers, dealing with text (strings) is one of the most common aspects of any programming language (loading them, reading them, formatting them, concatenating them, converting them, printing them out, etc.). This section also deals with Escape characters and how to make sure that you are printing what you think you are printing.

Variables and Assignment

This provides a quick lesson in variable assignment and how to overwrite previous variables, assign new ones, and work with them correctly when they are integers, floats or strings.

Mixing It Up

As stated, this is where the various parts start to come together. Handling strings with numbers, converting numbers to strings, using gets to store input from the keyboard or user input for later use, using chomp to cot off the newline at the end of an input string meant for gets, and understanding the error message the debugger gets when a programmer mixes their variables up.

More About Methods

Ever wondered how to sort strings, print variables in reverse, get the number of characters in a string, change the case, or automatically capitalize/de-capitalize strings? This section walks you though doing exactly that, along with how to center, left justify and right justify lines of text so that they appear where you want to see them. This section also covers some higher math functions such as exponentiation, modulus, absolute values, random number generation, and our ever favorite trigonometric functions (sin, cos, tan, etc.).

Flow Control

Programs are very basic unless there is some ways to handle comparisons, branching and repetition. This section demonstrates the comparison options along with the if, elsif, else, and while methods. It also shows how to evaluate statements with ==, <,>, <=, =>, || and &&.

Arrays and Iterators

The ability to handle text and multiple items (integers and strings) relies on the ability to store them in arrays. This chapter goes though the options and syntax required to access elements in arrays as well as how to address and manipulate those elements using the each method and manipulating arrays with options like push, pop, join, first, length and last.

Writing Your Own Methods

The oft repeated DRY philosophy meets its saving grace. Ruby methods work the way functions and procedures do in other languages. They are contained sections of code that allow the user to reuse sections of code without too much unneeded repetition. The def command is used to “define” methods and their parameters. Local variables and local scope are introduced, and the ability to make sure that what you are working on in one method will not affect other variables elsewhere in the program. This section also covers return values (because like the classic mathematical functions, each method does return a value, even if its nil).

There’s Nothing New to Learn in Chapter 10

Don’t you just love titles like that? Well, it’s not entirely accurate, but the spirit is in the right place! While it doesn’t really teach new concepts, it does reframe the ones we’ve already learned to help us understand two important concepts, recursion (when a method calls itself) and sorting (which... well, I’m sure you can figure *that* one out ;) ). Unlike the previous sorting example, though, the book encourages you to create your own with the tools thus far learned.

Reading and Writing, Saving and Loading, Yin and...

So far, the programs we have written have been self contained and have had limited opportunity to wreak havoc on a system. This all changes with this chapter, because now we get the tools to create, read, write to an destroy files. We are introduced to the File.open, File.read and File.write methods (and how cool is it that Ruby automatically closes any file call that’s made when it reaches end?). We also get to experience the hotness that is YAML (which is a way to represent multi-line strings), and wrap our heads around how to accurately quote strings so that they appear the way we expect them to. The last part of the chapter shows a cool way to rename a directories worth of files to a reliable string and integer counter naming scheme (like you would use for photographs).

New Classes of Objects

We go back and revisit classes and show some tricks with some common ones (gotta’ admit, I didn’t know you could use Array.new and String.new that way. Interesting : )). Time is examined and the various methods that can be used with it (including Time.gm, just in case you were curious as to what the time is GMT). The hash class is discussed and compared to an array, but unlike an array doesn’t require a specific ordering. as long as a pair is represented, Ruby will know how to find it. Additionally, the chapter also covers the class class (no, that’s not a repeat, you can actually use a method called class on the class called class... these are admittedly the esoteric bits that normally make me shy away from programming ;) ).

Creating New Classes, Changing Existing Ones

This section walks you through the creation of a class and adding methods to it. Additionally , Instance variables are also covered and explained (that ‘@’ symbol that pops up in Ruby code). initialize gets some stage time and an explanation of the difference between new and initialize is given (new is a class method, initialize is an instance method). the difference between public and private classes are described (along with a somewhat active baby dragon... sorry, you’ll just have to read the book to figure *that* one out :) ).

Blocks and Procs

This sections shows how to take a block of code and make an object out of it. Procs can take parameters or just be called as is, but respond with the call method. The key takeaway with this is that procs can be passed to other methods, where methods cannot be passed to each other. Methods are not objects. Procs are. It’s esoteric (at least to me) but it’s kinda’ cool, too :).

Beyond This Fine Book

Now don’t go thinking that just because you got to here that you are a Ruby expert. You have learned a smattering of Ruby and enough to maybe “watch some Anime” with my Japanese example above. While I’ve learned some details about programming in general and with Ruby in particular, there’s a bunch more out there that I’ll need to digest and practice with before I can say i’m doing anything productive or useful. Tools like irb are discussed in this chapter to help us get a little bit more out of what we can do with the language. A sales pitch is made for “the Pick Axe” which is the book “Programming Ruby”, as well as for the Ruby-Talk mailing list (mirrored at comp.lang.ruby for those of you out there who still understand USENET hierarchy, or even know what USENET is ;) ).

Possible Solutions

Interested in seeing the possible ways the “More to Work on” problems could be solved? Chris has made a listing of “possible solutions”. Why possible solutions? Because “There’s More Than One Way To Do It”, also acronym’d as TMTOWTDI or “Tim Toady”. The point was that, in the first edition of the book, there were no solutions provided, and this cause quite a few complaints. In the second edition, each exercise gets a “How You Could Do It” answer and a “How I Would Do It” answer (note, these pages take up much of the 2nd half of the book. It’s a 150 page book without the Solutions list and index).

Bottom Line:

It’s snarky, it’s irreverent, it’s even borderline silly at times, but I’ll give it credit, it is effective at what it sets out to do, and that’s provide a novice with a programming primer in Ruby. It doesn’t cover everything, nor does it intend to. Learning to Program with Ruby is a good first place to spend some time and practice with the language and learn the fundamentals before jumping into another book (I also have Everyday Scripting with Ruby, which will be my next adventure in this vein along with The RSpec Book).

I feel Chris’ book has given me a leg up to better understand what I’ll need to know to better understand and more quickly read the other books, now that I feel I have a better understanding of how the Ruby blocks fit together. For some, the tone and the attitude of the book may prove to be a turn-off. I found it to be fun and entertaining, and thus, something I was more willing to read to get those “quick wins” and gain an understanding of the language in a less confusing manner. Other books may prove to be worthwhile and offer different perspectives, but for a quick win and a comfortable first look, this ain’t bad at all.

Learn to Program, Second Edition (The Facets of Ruby Series)


Andy Tinkham said...

Nice review, Michael! If you want recommendations for other good Ruby books to help in your journey, I'd recommend both of Russ Olsen's books - Design Patterns in Ruby and Eloquent Ruby. They have a similar style to what it sounds like Pine has, and I've found them to be very readable.

Michael Larsen said...

Hi Andy thanks for the recommendations. As soon as I'm through with my curent pile of books I will definitely check these titles out :).

Jeremy Wenisch said...

Thanks for this review, Michael. I'm just about through Everyday Scripting With Ruby, which I've really enjoyed. It's my first exposure both to Ruby and TDD, and this has been a pleasant introduction. I will have to keep Learn to Program in mind when look for more.