Sunday, November 20, 2011

Exercise 23: Read Some Code: Learn Ruby the Hard Way: Practicum

So I'm realizing something... I guess I've been a little too focused to pay attention. There are 52 Exercises in this book. There are fifty two weeks in a year. As I'm focusing on a chapter and a synopsis every day, that means I'm trucking through a weeks worth of material in a day. Sometimes that's not a big deal. Sometimes, though, it means there's a big chunk to bite off in a given day. This might be one of those days :).

Anyway, the goal of this lesson is reading code on the Internet. As Zed has pointed out, the goal isn't to get us to understand code, but to teach the following three skills:

  • Finding Ruby source code for things you need. 
  • Reading through the code and looking for files. 
  • Trying to understand code you find.

In many ways, this is what I'm currently doing on a regular basis when it comes to Cucumber, Capybara, Rspec and Ruby. I find stuff, I analyze it, I try to figure out if it will work as a standalone step definition, and then I try it out. Often, I strike it lucky and the steps just work, sometimes I have to fiddle with them and try different values. It feels a lot like going to a different country and winging it trying to get around. Awkward at first, but if you pay attention, you start to get a lay of the land and enough conversational skills to be dangerous :).

So let's see what we find today..

  • Go to with your favorite web browser and search for "ruby". 
  • Pick a random project and click on it. 
  • Click on the Source tab and browse through the list of files and directories until you find a .rb file. 
  • Start at the top and read through it, taking notes on what you think it does. 
  • If any symbols or strange words seem to interest you, write them down to research later.

[OK, based on this, I decided to check out jekyll, which can be seen here:

Jekyll is a way to generate a static web site that will run with Apache or other web servers. In any event I dug into the main file and here's what I found that had me wondering "what am I looking at here?":

$:.unshift File.join(File.dirname(__FILE__), *%w[.. lib])

exec = {}
options = {}

opts.on("--file [PATH]", "File to import from") do |import_file|
  options['file'] = import_file

I see blocks like the above structured a lot, and I've even used them lots of times, but I don't entirely get what it is they are doing. I've used do-while loops in other languages, but this isn't a loop per se. Anyway, I'm looking forward to finally getting an explanation as to what this actually is and why it's formatted this way.

opts.on("--paginate [POSTS_PER_PAGE]", "Paginate a blog's posts") do |per_page|
      options['paginate'] = per_page.to_i
      raise ArgumentError if options['paginate'] == 0
      puts 'you must specify a number of posts by page bigger than 0'
   exit 0

So far, we haven't done much if any error handling, so I'm interested in checking out more about how this works and why.

opts.parse! (what does the "!" mean?)

That's it. Your job is to use what you know so far and see if you can read the code and get a grasp of what it does. Try skimming the code first, and then read it in detail. Maybe also try taking very difficult parts and reading each symbol you know out loud.

[I was actually fairly surprised how much I could actively read. Sure some of the nuances or the functions being called and the methods felt a little weird, but I understood what they were and where they were being called from, and could go look there and see what was being defined. That felt a lot better than I thought it would :) ].

Now try several other sites:

On each of these sites you may find weird files ending in .c so stick to .rb files like the ones you have written in this book.

A final fun thing to do is use the above four sources of Ruby code and type in topics you are interested in instead of "ruby". Search for "journalism", "cooking", "physics", or anything you are curious about. Chances are there's some code out there you could use right away.

[I checked out and searched for music, just to see what I could find. I found music-utils, thought it looked promising, and dug in. I think it's pretty cool to see how Ruby handles things I understand abstractly in a musical sense and how it is rendered in code. Not at all how I expected it to be, but after a few passes a lot of the details make sense. An example:


This is a cool experiment, and it's one I have a greater appreciation for now that I have done it. I think it's a good idea to take some time and go read someone else's code, partly to get new ideas and try out/plug in stuff that looks promising, but more to the point, see if you get what's being written. The best way to make sure you comprehend stuff is to keep reading, and when you come across a word you don't understand, write it down, look it up, ponder the definition, and then keep reading. Next time you come across that word, hey, you'll be ready for it and understand it. If the definition you have doesn't quite seem to fit, look it up again; see if there are alternate meanings. One of them may fit... then keep doing that. As in literature, writing that was once impenetrable becomes decipherable at first, and then fairly easy with frequency. Code looks to be much the same way.

No comments: