October 14, 2010

Posted by John

Tagged rants

Older: Building an Object Mapper: Override-able Accessors

Newer: The Chain Gang

Stop Googling

Yesterday, one of my inter-web buddies IM’d me and asked if I had used Typhoeus before. I said yes, so he asked me if it was possible to follow redirects using it. He said he google’d it and nothing turned up.

I sharply responded, “LOOK AT THE CODE!”. We had some banter back and forth and a few minutes later he was automatically following redirects. It seems these days that developers often think if something does not turn up in a google search, it does not exist.

The John Nunemaker Approach

So how would I have approached my dudes problem?

  1. Open a browser and type in github.com.
  2. Search for typhoeus.
  3. Click on Paul Dix’s repo.
  4. Click on lib/. lib is always where the guts of any Ruby gem are so it is a sensible first start.
  5. Click on typheous/. Not the ruby file, but the directory. Most good gems just have miscellaneous top level things in the ruby file of the gem name. All the guts sit in the folder named after the gem.
  6. Scanned for and clicked on the file named request.rb, which seemed like a good place to start, since we are looking to make a request.
  7. Starting at line 5 there is an attr_accessor full of options, two of which stuck out to me — follow_location and max_redirects. Both of these seemed related to what he was trying to do. I also noticed right below that Paul has some inline documentation which mentions all the options, including the aforementioned ones.
  8. Copied the link to the file, IM’d it to my dude and yelled again, “LOOK AT THE CODE!”

If you do not know me, you may think I was a bit harsh breaking out the all caps, but it was all in good fun. The point, however, is not in good fun. It is deathly serious. As developers, we write code. If you can write code, you should also be able to read code.

The Side Effects

Beyond the fact that you will most likely find exactly the answer you are looking for, there are some other side effects.

First, as you look through the code, attempting to find your answer, you will quickly get a feeling for how the project is organized (or not organized). This helps determine if you really still want to use this project. If it looks like a mess, do not trust it. Find something else, or GASP, create your own project that does what you need. Repeating others is good.

Second, over time you will soak in more and more different coding styles and techniques. This will help you in your continuing efforts to get better as you are no longer in a box only looking at your own code. Several other people have expounded on the benefits of code reading so I will not dive in deep on that topic here, but suffice to say, it is really valuable.

Third, you will learn more about how the project works and may discover there is a better way to do what you are attempting. Some hidden option that no one has blogged about or utility class with handy helper methods.

Fourth, you will get faster and faster at tracking down where code is that you need. You will learn quickly how to find project’s code and where to find the code you need in the project. The steps above that describe my approach typically take me about the same amount of time as it would to search on google.

Fifth, and finally, and maybe most importantly, you will become addicted to reading code. You will start to shiver and shake when you have not had your fix in a few days. You mind will begin to race with ideas. You will see how someone else solved a problem and think of better ways.

You will create. You will improve.

Conclusion

Ensure that GitHub is always near your fingertips. Install gemedit or a similar utility. Next time you go to google for an answer, stop, break open the code and learn. Here is hoping this article lights some peeps on fire instead of lighting a fire for them.

62 Comments

  1. Awesome post! I will check out gemedit. The `gem which` command is also useful to find the path to an installed gem.

  2. Is there a “let me Github that for you”?

  3. @Brian: I was totally thinking that as I wrote the post. I am far too lazy to create it though.

  4. While I agree that reading the source (and tests) will teach you a lot about the code, I still think thoroughly documenting your code is very important. Let’s not forget to do that because we think our code is readable.

  5. If there is not a google answer, you should blog about it. You’ll quickly be the “authoritative” answer for your own question.

  6. @Jeff: Agreed. That is why I have been working on MongoMapper documentation over features right now, since it is pretty stable.

    @Jason: Another good point. If you cannot find it in google, figure it out and then blog about it.

  7. Great reminder, thanks! I find myself opening up gems in Textmate a lot – the mate binary makes it easy to pop open a gem from terminal.

  8. Dan Croak Dan Croak

    Oct 14, 2010

    Google “github typhoeus”
    git clone repo
    ack “redirect” lib

  9. @Dan: Yep, same idea. Get at the code.

  10. @John: While my first comment wasn’t a direct stab at MongoMapper, that’s really nice to hear. :)

    @Jason: Exactly. While reading code to figure stuff out is great, I think we should strive for good documentation. Contributing by documenting stuff on your own blog is a great idea.

  11. Good post. I also love open_gem for that purpose.

    It adds an “open” command to gem. Eg. gem open activerecord loads the AR source code in your editor (at least if it does directories like TextMate or Redcar do).

  12. Check out open_gem for a quick way to read installed gems.

    Then this is all it takes:

    gem open mongo_mapper

  13. YES YES YES!

    I could not agree more. Great stuff, John.

  14. @Jeff: Ha. I did not think it was a stab, was just making a point that I agree. No worries. :)

  15. This is not said often enough. Thanks!

  16. And while you’re browsing github, use GHFinder (especially the bookmarklet)

  17. Sean Cribbs Sean Cribbs

    Oct 14, 2010

    gem which some/ruby/file | xargs $EDITOR

    That always works for me. Anyway, YES YES YES read the code, especially when Ruby is generally easy to read.

  18. Great article John! BTW, you can get the job done fast and easy with GithubFinder and Google Code Search filtering by package like

    follow_location package:git://github.com/pauldix/typhoeus.git

  19. Yep, I love GHFinder. Use it every day.

  20. If you’re too lazy to read the code, at least read the tests – if the behavior you’re looking for is tested, you now know two things:

    1) how to use it
    2) it probably works :)

  21. David Burrows David Burrows

    Oct 14, 2010

    It’s a good job you looked at Typhoeus as this wouldn’t have had the same nice ending for a lot of the gems out there!

    Perhaps the steps should be:

    1) LOOK AT THE CODE!
    2) IF IT LOOKS TERRIBLE FIND ANOTHER GEM!

  22. Yeah, I’m too often guilty of googling first. Hanging out with you has definitely pushed me to look at the code first though. Now when I catch myself opening up google first I give myself a stern nunemaker talking to :P

  23. I have a shell function “f” which cds me into the project directory. However, if you pass it a git repo url it checks it out first, then cds. Browsing new code a sinch this way.

    f http://github.com/jnunemaker/mongomapper.git
    mate .

    (I chose “f” for speed, it is on the left index finger)

  24. @Mando: 3) And it will continue to work. Things that are tested typically hang around.

    @David: Yep. That is exactly why I look at gems before I use them. No tests or unorganized code means I keep looking or write it myself.

    @Jon: Yay! Good to hear.

  25. I have a shell function “f” which cds me into the project directory. However, if you pass it a git repo url it checks it out first, then cds. Browsing new code a sinch this way.

    f http://github.com/jnunemaker/mongomapper.git
    mate .

    (I chose “f” for speed, it is on the left index finger)

  26. @Chris Lloyd: Nice. I put all of my code in ~/dev/ruby/code. Tons of cloned repos there. When I am just looking something up quick, I use GHFinder or GitHub. When I really need to dig in, I always clone the full repo and open it up in an editor.

  27. Haven’t tried gem open, but if it’s me, I just ack it. ack > google.

  28. @Giles Bowkett: ack is great. I use that as well. Amazing how many different ways there are to do the same thing: scour code.

  29. BTW, bundler has a built in option to open gems in your $EDITOR as well. bundle open I like this over open_gem because bundle open sets my working directory automatically when it opens the gem up in Vim.

  30. @Joey Beninghove: Oh, wow. I guess I need to read the bundler code. Somehow missed that one. I had a shortcut that did something similar.

  31. @John Nunemaker: Thanks for the gemedit plug!

    @Joey Beninghove: Working directory change is coming to gemedit soon.

  32. A wise man once told me, “Use the source, Luke.” Spot on.

  33. @andy — i could go for a `gem which` right about now

    ..

  34. Thx for the great article, and I could not agree more!

    I really feel like reading code helps me get better, find new ways to do things, and in general makes my thinking a little faster.

    I think I am not so far from needing my “fix” everyday ;-)

  35. Steve Loveless Steve Loveless

    Oct 14, 2010

    While I don’t disagree at all, it’s definitely worth noting that Ruby has some of the best documentation tools in the biz. Running rdoc or yard on your gem’s base dir, then pulling that up in a web browser is also a go-to option for me.

  36. mate `bundle show typhoeus`

  37. I’d highly recommend GithubFinder, a tool that I wrote to quickly browse any github repo. Basically you won’t even need to clone the repo locally or download the code. The interface is blazingly fast with full keyboard support. And you can also diff the file with previous revisions as well.

    http://sr3d.github.com/GithubFinder/

    and the main repo is

    http://github.com/sr3d/GithubFinder/

    Cheers!

    Alex

  38. One of those things that you probably shouldn’t have to tell an audience voluntarily reading a blog on software development, but I think we all fall into lazy habits sometimes. Anyway, thanks for the reminder.

  39. Joel Parker Henderson Joel Parker Henderson

    Oct 14, 2010

    Google is excellent if you use it well.

    google: typhoeus redirect filetype:rb site:github.com

  40. Joey Beninghove: But unless I’m confused gem open and bundle open don’t do quite the same thing. bundle open seems to require that I already be in the directory where the gem lives (i.e., that I cd there first). gem open, on the other hand, works from anywhere. I’m curious to know if I’m wrong, since I was already thinking that gem open would be more helpful for vim users if it set vim’s working directory to the gem source.

  41. The fact that Ruby uses gems and not “co-located” files was a major barrier for a PHP guy like me – as I was used to have all libs and the like right on my project’s folder.

    Luckily, things like ‘gem which’ and ‘grep’ got me around my need for reading code. But I feel like it might be an invite for googling for the newcomers that don’t really get how to go about finding the gem code.

    Good read, thanks for that!

  42. Great post. I would say the same thing for man pages. A former co-worker of mine was always reading man pages and RFCs, and let me tell you, you start to look really stupid next to a guy like that if the only thing you know how to do it read a solution to a problem from someone’s blog!

  43. Let me alter the list (for us that runs startups and got deadlines):

    if it’s feels like a tiny patch:

    1) Look at the code using say “open_gem” (or GitHub)
    2) Fork and patch

    If weird errors that makes no sense:

    1) Google it
    2) Search mailing-lists if any
    3) Look at the code using say “open_gem” (or GitHub)
    3.a) if no clue or too much work: ask author kindly or nuke the dependency
    3.b) Fork and patch

    Not Google it at all is just not a wise thing if time is a factor.

  44. Totally agree. I’m always pointing friends asking questions to the code. Sometimes it leads to patches for the projects! Another great post John.

  45. Spot on! Love your codez, man.

    So I was about to mention the whole ‘bundle open’ thing and then I took your advice and opened that shit up. Turns out it looks for $BUNDLER_EDITOR and $VISUAL before $EDITOR. Now we know!

  46. @Peter Aronoff,
    No, “bundle open” doesn’t require you to be in the gem directory. I use it all the time simply from the root of my rails app. ~/code/my_app $ bundle open devise // as an example. Works great.

  47. I completely agree with what you’re saying here. I think we’re a bit spoiled in the ruby/rails community, in that we expect things to “just work”. When they don’t “just work” many of us expect a readily available quick fix (i.e. google) or maybe even just upgrade the gem and hopefully it will work ;)

    So yea, I agree, we should all get more comfortable reading code. I would argue it’s one of the most important skills a developer can attain. And yes, ack FTW.

  48. Kelvin J Kelvin J

    Oct 14, 2010

    Wow… and we’re living in Utopia!

    Look at a practical example:

    1. You’re working on a project for a client with… wait for it… deadlines!
    2. You’re using a framework with poor documentation, like Zend Framework (spits)
    3. You hit a barrier and need to figure out how to do something with the Framework

    In the real world, you want to get the answer as soon as possible. How do you do this?

    1. Google it
    2. Ask someone who has a better knowledge of the Framework than you (hey, even if they don’t know they might know where to look)
    3. Get into the bloody code

    So, IMO, your inter-web buddy was doing the right thing.

    You could sink hours into looking through the nightmarish over-engineered code, but

  49. Nice post.
    If i can’t find an answer, i try to tweet it, instead of using my blog. Tweets are reaching people right after clicking the send button… till someone finds my blopost, hours/days are gone ;-)

  50. Thanks for your post.
    I really agree with you.

  51. Well said. I am often surprised at how hard it is for some developers to read code, even their own!

  52. I read this more as a call to action than a rant. And it worked — I’ve decided to start by installing Rails to my server and tinker.

  53. It’s handy to have both gemedit and bundle open — of course bundle open requires that you’re in a project directory with a Gemfile and thus you’re opening the version that your app uses, but it will also open libraries for which you’re using :git or :path sources in said Gemfile. It’s especially dreamy when your installed :git code is tucked away in an RVM gemset directory.

  54. For you Vim+NERDTree users:

    echo '#!/bin/bash' >> ~/bin/bvim
    echo 'cd $1 && vim +NERDTree'  >> ~/bin/bvim
    export BUNDLER_EDITOR=~/bin/bvim
    export GEM_OPEN_EDITOR=~bin/bvim
    

    You get the idea.

  55. “Deathly serious”? Really?

    What hyperbole will you resort to when something actually is deathly serious?

  56. @Dave: I would probably have to add for realz at the end so people knew.

  57. Why is there no “find” in GithubFinder? Quite an irony.

    Also, I’m a huge TDD fan, but when I’m diving into a strange library, I don’t even read tests, mostly, since code never lies and tests are often confusing and have hidden setup and fixtures and DSLs and stuff.

  58. I don’t know why, but I always check the documentation first. I’m almost always disappointed, and immediately turn to the code. Maybe I’m just an optimist, but surely good documentation shouldn’t be such a rare beast?

    Not to toot my own horn by way of example or anything, but a simple page like this helps immensely I think: http://signet.rubyforge.org/

  59. @Alex Chaffee
    The “Finder” in GithubFinder comes from Mac OS X’s Finder, since the UI of GHF is inspired after Finder. To implement a full search of the repo will require a lot of requests to the Github API, e.g. there’s no clean way to do it right now.

    Another approach is to clone the repo and perform a search locally. This is a viable approach but it would be hard to scale up since now we’re dealing with a lot of repo data and clean up. Moreover the app is pretty much running with 0-server side component at the moment, I’m just using gh-pages to serve it up and that simplifies the deployment a lot. Unless Github comes up with a new API to retrieve all the listing of the files, then I don’t see how “find” can be implemented anytime soon.

  60. I think this is a good point, and people should look at the code more often (I am often guilty of not doing so). But isn’t that a nice benefit of having smart friends, so that you can turn to them for help with something they’ve done before? This kinda seems like it’s bordering on a rude “RTFM” approach.

  61. I’d take exception, first on general grounds. If a library’s client has to read its source to figure out how to use it, it’s not done right. There’s a million reasons why well-defined interfaces are a good idea, and exposing implementations is mostly not.

    The specifics of your argument don’t stand either. Reading code is a bad way of understanding design. One well-written line of documentation is worth multiple lines of code – English is intensely more informative than Ruby.

    By extension, it is indeed more productive to Google or ask, and that’s why people do it automatically – shortest-path problem solving rules, as it should.

  62. I’d take exception, first on general grounds. If a library’s client has to read its source to figure out how to use it, it’s not done right. There’s a million reasons why well-defined interfaces are a good idea, and exposing implementations is mostly not.

    The specifics of your argument don’t stand either. Reading code is a bad way of understanding design. One well-written line of documentation is worth multiple lines of code – English is intensely more informative than Ruby.

    By extension, it is indeed more productive to Google or ask, and that’s why people do it automatically – shortest-path problem solving rules, as it should.

Sorry, comments are closed for this article to ease the burden of pruning spam.

About

Authored by John Nunemaker (Noo-neh-maker), a programmer who has fallen deeply in love with Ruby. Learn More.

Projects

Flipper
Release your software more often with fewer problems.
Flip your features.