Book Review: The Book of Ruby
Last month No Starch Press released their second Ruby book ever, The Book of Ruby by Huw Collingbourne. Their first was Ruby by Example, released four years ago in 2007! The Book of Ruby is an introductory book to the Ruby programming language.
The book covers all of the standard programming language basics: strings, classes, arrays, loops, etc. Additionally there are three chapters on more advanced subjects in Ruby: Marshal, Threads, and Dynamic Programming. Ruby on Rails is also quickly introduced in a chapter at the end of the book.
Each chapter includes a Digging Deeper section at the end that goes into more detail, warns about corner cases, or introduces an advanced usage. As someone who already knows Ruby these were the most interesting to read. They are placed inside of their own section to let someone who is just trying to learn Ruby know that they can safely be skipped.
No Starch Press is the publisher behind several fun programming books like Land of Lisp, Learn You a Haskell for Great Good, and the iconic Manga guides. When I picked up The Book of Ruby I wasn’t expecting to encounter the second coming of Why’s (Poignant) Guide to Ruby, but that’s what I was hoping for. Unfortunately, The Book of Ruby does not share any characteristics with that fun intro to programming Ruby and instead reads like an average technical book… dryly. On the positive side, I did find the author’s writing to be clear and easy to follow.
The book contains many examples but they are as contrived as possible. I understand that examples should be as simple as possible so that the reader can easily follow along but there is also a need to make the examples do interesting things to make the book more engaging.
Further, Collingbourne does not make an attempt to explain how Ruby is actually used “in the wild”. This is something that another Ruby author, Russ Olsen, does really well. Ruby has a lot of features so it is important to understand how Ruby programmers actually use Ruby. For instance, even though class variables are available, Ruby programmers try to never use them. This is something I would have liked to know when learning Ruby. However, instead of sharing these tidbits of information from his many years of Ruby experience, Collingbourne stays neutral and presents all of the information without including his opinions.
The one opinion that Collingbourne did share, is that he does not believe code style conventions are very important. This is something I can respect, and actually envy. In my own programming, I consider the time I spend to reformat my code to make it “look pretty” to be a waste. However, I still do it because it drives me crazy not to. If I could flip a switch inside my brain that would cause me to not care about code style anymore I absolutely would.
Overall, I feel like if this had been the first Ruby book I had picked up I would not have fallen in love with Ruby like I did. I am disappointed with No Starch Press for not upholding their unique style. The Book of Ruby does not differentiate itself enough to recommend over the other Ruby titles that are out there.
Capturing Output from PUTS in Ruby
When writing unit tests for my simplesem interpreter, one test in particular was problematic. In simplesem, the set write instruction prints output to the screen.
// place Hello World! on the 'write' buffer set write, "Hello World!"
Internally, the interpreter is just passing the second parameter, “Hello World!”, to the puts method in Ruby. This makes it difficult to use traditional test/unit assertions to check that the simplesem instruction is working.
I eventually found two solutions for this. The first, suggested by David Stevenson at Pivotal Labs, is to use mocha to check that puts was called on the object.
require 'test/unit' require 'rubygems' require 'mocha' class SimpleSemParserTest < Test::Unit::TestCase def test_set_stmt_write parser = SimpleSemParser.new parser.expects(:puts).with("Hello World!") parser.parse('set write, "Hello World!"').execute end end
This solution is fine for most situations; Mocha will throw an exception if puts is not called. However in my case, it was unsuitable because puts was not being called on the SimpleSemParser object but instead on a Treetop syntax node that I did not easily have access to within the unit test.
I knew that if I could capture the output from the puts method into a variable I would be able write the test using a standard assert_equal. After some googling I discovered that this functionality is built into the ZenTest gem. After rewriting the test looked like this.
require 'test/zentest_assertions' class SimpleSemParserTest < Test::Unit::TestCase def test_set_stmt_write out, err = util_capture do parser = SimpleSemParser.new parser.parse('set write, "Hello World!"').execute end assert_equal "Hello World!\n", out.string end end
This works great. However, should we decided that we do not want to use an external gem, with a little effort we can bypass ZenTest and implement util_capture ourselves.
A SIMPLESEM Interpreter
In my Programming Languages course, taught by Shannon Tauro we have been using a fake assembly language of sorts called SIMPLESEM to gain experience translating the semantics of a high level programming language, to a simple processor.
Since SIMPLESEM is a made up language that was created just for our textbook, there was no way for me to execute the SIMPLESEM programs that I was writing for the homework assignments. This was annoying because SIMPLESEM is a low level language which makes it hard to notice mistakes. Of course, it is very easy to make a mistake any time you are programming but it is even harder to catch those mistakes if you are working at close to assembly level.
As a fun exercise I implemented an interpreter for SIMPLESEM using Ruby and published it as a RubyGem. Fortunately, I choose to use Nathan Sobo’s Treetop gem to aide in the development. Using Treetop, I wrote a parsing expression grammar to parse SIMPLESEM commands. This resulted in my SIMPLESEM interpreter being a lot more flexible than I had originally anticipated. After I familiarized myself with the basics of writing Treetop grammars I found it very easy to make changes to my grammar definitions to add language features one by one.
Rails-doc.org is my new Rails Reference
When working with a framework as large as Ruby on Rails its necessary to have a reference close by for… well just about everything. Until recently I was a big fan of gotAPI.com because I really appreciated the Ruby and Rails reference tied together. However, the Javascript autocomplete on their search box is broken in Firefox 3 so I decided to try the new Rails reference site, Rails-doc.org.
Rails-doc.org is an fairly ambitious project to create a community driven Rails documentation site. Basically they let users sign up and contribute notes to the existing Rails documentation. This certainly has the potential to be very useful, especially for new Rails hackers because sometimes the people who have been around the framework for a while just take things for granted.
Take the documentation for strftime in the Date class for example. There is no documentation listed for that method. Despite the fact that you clearly need documentation of the strftime options in order to use that method. Instead you have to know to look under strftime in the Time class for the documentation. While this is an example specific to Ruby documentation, these are the kinds of obvious problems that a community documentation website can help solve.
Right now Rails-doc.org has only been live for a month the so amount of community documentation feels very low. In the mean time I’ll be using the site for the official documentation that is already in place. Plus its the best looking rendering of the Rails documentation site out there. The Nodeta guys did a good job with the design. They also have a nice looking blog.
It will be interested to see how many of the notes contributed to Rails-doc get ported to the official Rails documentation. This certainly feels like the easiest and most straightforward way to contribute to Rails documentation and I can see it becoming a testing ground for future contributions to the official docs.
Ruby-Poker 0.3.0
Ruby Poker has been updated! This release is largely a result of bug reports filed by Jim W. He took ruby poker to areas I had not previously thought to explore and he ran into a couple nasty bugs. They have all been fixed in Ruby-Poker 0.3.0. In addition the following changes were made that users should be aware of.
