post

Writing Readable Code
Writing Readable Code

Writing code in Ruby is a real pleasure. It’s a very expressive language, and that allows me to make complex programming problems read like English.

For instance, at work recently I needed to authenticate against a separate system (written in .NET). I also needed to cache the user to the application’s DB for speed and convenience. And I also needed to make sure the cached version gets updated if the .NET version gets updated. Etc. Etc. Etc. The point is there was a lot to do there, but it didn’t have to appear that way.

User.process_login(username, password)

Once that complicated mess is abstracted, that’s all I have to do. Here’s a piece of the mixed in module that does a little more of the dirty work:

def process_login(username, password)
  returning Proxy.authenticate(username, password) do |user|
    cache! user if user && user.needs_cached?
  end
end

Proxy is a class that nicely handles the WSDL/SOAP communication to the .NET system; the authenticate method on the Proxy authenticates against the .NET system’s DB; the cache! method (you guessed it) does the caching based on a last-modified date comparison of the returned SOAP user versus the cached version (if there even is one). The returning part simply returns the user object or nil, depending on if the authentication was successful or not.

Hopefully you’re thinking, “there was really no need to explain all of that.” Because the goal here isn’t to focus on all of the behind-the-scenes mumbo-jumbo, it’s to give yet another example of how clearly a complex thing can be written in Ruby.

I might even be able to show that to my Mom and have her tell me what it’s doing. Well, maybe not, but the average (technically-minded) person would have no problem.

As an aside, this is what I’m really starting to love about Rspec. It sort of guides your mind into writing readable code, which I’m all about.

Comments
01
_eric
01 Apr 2008 11:50 PM

I believe you may be misusing returning a little bit.

This may work a little better:

def process_login(username, password)
  returning Proxy.authenticate(username, password) do |user|
    cache! user if user && user.needs_cached?
  end
end
02
_eric
02 Apr 2008 07:25 AM

Actually… I didn’t realize the example for “returning” shows both. That is strange.

I do feel that the version I posted feels a bit more “Ruby” than the other… but I suppose that’s just a matter of personal taste.

03
02 Apr 2008 08:02 AM

Yes, I’ll have to agree with you, your version does feel a bit more Ruby-ish. I’ve taken both approaches in the past, and don’t really have a reason for choosing “user =” over “do |user|” in this particular case (or any case, really). The first time I learned about returning, I believe I took the “user =” approach, and I guess old habits are hard to break :-)

I’ll update the example to reflect your suggestion.




Please rewrite the image text in the SPAM field: Spam Protection

Preview

2008 by Ryan Heath | Get In Touch

flickr

DesolateInfinityLooking upDazedBlurred