October 14, 2010
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?
- Open a browser and type in github.com.
- Search for typhoeus.
- Click on Paul Dix’s repo.
- Click on lib/. lib is always where the guts of any Ruby gem are so it is a sensible first start.
- 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.
- 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.
- 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.
- 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
Oct 14, 2010
Awesome post! I will check out gemedit. The `gem which` command is also useful to find the path to an installed gem.
Oct 14, 2010
Is there a “let me Github that for you”?
Oct 14, 2010
@Brian: I was totally thinking that as I wrote the post. I am far too lazy to create it though.
Oct 14, 2010
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.
Oct 14, 2010
If there is not a google answer, you should blog about it. You’ll quickly be the “authoritative” answer for your own question.
Oct 14, 2010
@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.
Oct 14, 2010
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.
Oct 14, 2010
Google “github typhoeus”
git clone repo
ack “redirect” lib
Oct 14, 2010
@Dan: Yep, same idea. Get at the code.
Oct 14, 2010
@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.
Oct 14, 2010
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).
Oct 14, 2010
Check out open_gem for a quick way to read installed gems.
Then this is all it takes:
Oct 14, 2010
YES YES YES!
I could not agree more. Great stuff, John.
Oct 14, 2010
@Jeff: Ha. I did not think it was a stab, was just making a point that I agree. No worries. :)
Oct 14, 2010
This is not said often enough. Thanks!
Oct 14, 2010
And while you’re browsing github, use GHFinder (especially the bookmarklet)
Oct 14, 2010
That always works for me. Anyway, YES YES YES read the code, especially when Ruby is generally easy to read.
Oct 14, 2010
Great article John! BTW, you can get the job done fast and easy with GithubFinder and Google Code Search filtering by package like
Oct 14, 2010
Yep, I love GHFinder. Use it every day.
Oct 14, 2010
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 :)
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!
Oct 14, 2010
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
Oct 14, 2010
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.
(I chose “f” for speed, it is on the left index finger)
Oct 14, 2010
@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.
Oct 14, 2010
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.
(I chose “f” for speed, it is on the left index finger)
Oct 14, 2010
@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.
Oct 14, 2010
Haven’t tried
gem open
, but if it’s me, I justack
it.ack
> google.Oct 14, 2010
@Giles Bowkett: ack is great. I use that as well. Amazing how many different ways there are to do the same thing: scour code.
Oct 14, 2010
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.
Oct 14, 2010
@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.
Oct 14, 2010
@John Nunemaker: Thanks for the gemedit plug!
@Joey Beninghove: Working directory change is coming to gemedit soon.
Oct 14, 2010
A wise man once told me, “Use the source, Luke.” Spot on.
Oct 14, 2010
@andy — i could go for a `gem which` right about now
..
Oct 14, 2010
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 ;-)
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.
Oct 14, 2010
mate `bundle show typhoeus`
Oct 14, 2010
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
Oct 14, 2010
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.
Oct 14, 2010
Google is excellent if you use it well.
google: typhoeus redirect filetype:rb site:github.com
Oct 14, 2010
Joey Beninghove: But unless I’m confused
gem open
andbundle 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 Icd
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.Oct 14, 2010
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!
Oct 14, 2010
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!
Oct 14, 2010
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.
Oct 14, 2010
Totally agree. I’m always pointing friends asking questions to the code. Sometimes it leads to patches for the projects! Another great post John.
Oct 14, 2010
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!
Oct 14, 2010
@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.
Oct 14, 2010
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.
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
Oct 15, 2010
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 ;-)
Oct 15, 2010
Thanks for your post.
I really agree with you.
Oct 15, 2010
Well said. I am often surprised at how hard it is for some developers to read code, even their own!
Oct 15, 2010
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.
Oct 15, 2010
It’s handy to have both gemedit and
bundle open
— of coursebundle 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.Oct 15, 2010
For you Vim+NERDTree users:
You get the idea.
Oct 16, 2010
“Deathly serious”? Really?
What hyperbole will you resort to when something actually is deathly serious?
Oct 16, 2010
@Dave: I would probably have to add for realz at the end so people knew.
Oct 17, 2010
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.
Oct 19, 2010
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/
Oct 19, 2010
@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.
Oct 20, 2010
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.
Nov 19, 2010
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.
Nov 19, 2010
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.