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.

1
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:

1
2
3
4
5
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 on Tue Apr 01 at 07:50PM

I believe you may be misusing returning a little bit.

This may work a little better:

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

02

_eric on Wed Apr 02 at 03:25AM

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

Ryan on Wed Apr 02 at 04:02AM

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.

Have something to say?
Please rewrite the image text Are You Human? Hint: Are You Human? Formatting Tips

or

Popular Tags

Recent Comments

  • Wed Nov 19 by xxxRAWxxx

    There’s a new one for you. Can’t believe I stumbled ...

  • Wed Nov 19 by Chris

    @Ryan, @Nick – well, I’m glad I’ve been of help, ...

  • Tue Nov 18 by Ryan

    Ha! Yeah, it is a little awkward. Good thing I don’t actually...

  • Tue Nov 18 by Chris

    While your explanation is sound, I cannot bear the hear the audible...

  • Tue Nov 18 by Ryan

    I suggest looking into unobtrusive javascript, especially since you...

  • Tue Nov 18 by Nick

    Update – I found out that my inclusion of jQuery was causing ...

  • Tue Nov 18 by Nick

    I had something about 20% developed in PHP and got sick of it. It&#...

Flickr Photos

  • Desolate
  • Along the fence
  • Blurred
  • Darting
  • One rose left
  • Farm entry
  • Watch your step
  • Back to work

© 2008 Ryan Heath | Site Management A Ruby on Rails production.

Get in Touch