Simplifying Your Ruby Code

Posted by jeff Thursday, February 12, 2009 18:12:00 GMT

I used to write Ruby code like this a lot when I my brain was still half .NET.

def is_ready?
  if self.status > 3
    return true
  else
    return false
  end
end

I see this all the time on the Rails mailing list. Would you be surprised to know that you can write the same method this way:

def ready?
  self.status > 3
end

(I’d do away the the magic number “3” in favor of a constant, but I digress…)

Notice two things:

  • Methods that return a true/false indicator should end with a question mark. For more on this topic, see my other post on the topic of naming conventions in Ruby.
  • Ruby uses the last-evaluated expression as the return value. No need to wrap it with a useless if/else block.

Questions? Got another example of code patterns you’ve seen that could be simpler? Use Textile formatting in the comments.

Comments

Leave a response

  1. Chris Cyvas   February 12, 2009 @ 07:07 PM

    forgive my ignorance here as I’m not a Ruby programmer, but how is that different than:

    private IsReady(){ return this.status > 3 }

    Were you a VB.NET programmer? Maybe it’s language semantics, not .NET?

  2. Todd   February 12, 2009 @ 07:20 PM

    Chris,

    Are you really a C# developer? Your code won’t compile without the ’;’ after ‘this.status > 3’. lol.

  3. Jason   February 12, 2009 @ 10:13 PM

    So C# can just do “return (self.status>3)” ... ?

  4. John Walker   February 12, 2009 @ 10:21 PM

    Well, VB.NET handles it the same way…

    Function IsReady() as Boolean

    Return Me.Status > 3

    End Function

  5. Karmen Blake   February 12, 2009 @ 10:42 PM

    I have a collection of Ruby idioms I like to share: http://pastie.textmate.org/143799

  6. Thomas   February 12, 2009 @ 10:45 PM

    @Jason,

    Of course, you’re just returning the result of an expression. This way of doing it is pretty much common across all programming languages.

  7. Thomas   February 12, 2009 @ 10:47 PM

    @Chris,

    You could at least be a little more civil when making a point. The vb statement was a sad attempt at an insult.

  8. Chris Cyvas   February 13, 2009 @ 12:00 PM

    it wasn’t a dig on VB at all, I used to program in VB as well. I was curious about if the language constructs were influencing how he wrote code.

  9. Thomas   February 13, 2009 @ 12:19 PM

    @Chris,

    That response doesn’t make sense. The syntax differences between VB and C# don’t prevent you from returning the result of an expression, as mentioned by JW above.

    The problem here boils down to the fact that a lot of so-called programmers aren’t or weren’t experienced enough to know the ‘shortcuts’.

  10. Chris Cyvas   February 13, 2009 @ 05:19 PM

    Jeff,

    Were you a VB programmer? If so, I am wondering if you feel the language syntax or language constructs of VB may have impacted how you wrote the code? This isn’t a technical question, exactly, but more of a question on behaviour.

    The reason I am asking is because I have seen this before. I worked at a place that was primarliy a VB shop that then asked everyone to switch to C#. In that process, I saw a lot of what you cite here. Which made me ask the question above. I understand it is not a language limitation, I am just looking for your opinion on why it occurred in your case?

  11. Jeff   February 14, 2009 @ 04:19 AM

    Hi Chris,

    Thanks for the comments. I was writing a lot of C++, then C#. I probably wrote that if/else construct at least once in my day, but I came across it in reading .NET code more often than I do reading other people’s Ruby code.

    I think, in general, my C# code was a lot wordier than my Ruby code is. And that was my point – that when you switch to Ruby, there are constructs in Ruby that can often simplify your code. But you can keep writing “Ruby code that looks like C# code” (or whatever your previous language was) for a while, then later you pick up on Ruby nuances and tend to write code that’s more concise.

    Does that make sense?

    I wasn’t trying to pick on C# or VB per se, but just point out that often there are different ways to do the same thing in Ruby that can help you write a little less code. And a little less code everywhere adds up to a lot.

  12. Ryan Heath   February 14, 2009 @ 05:24 AM

    Well, something I see a lot (and used to do) is:

    do_something if x && !y

    Now I write that as:

    do_something if x unless y

    To me it just reads better, but I know some might argue that :-)

  13. Chris Cyvas   February 15, 2009 @ 01:44 PM

    Thank you for the insight Jeff!

  14. Chris Cyvas   February 15, 2009 @ 01:46 PM

    Also, FYI, this site renders funky in Chrome (my preferred browser). Since it’s probably a rails site, our app_browser file won’t help you, but it’s in the dC repo in case you need something to refer to.

  15. Dave   February 16, 2009 @ 03:39 AM

    I was going to echo Chris’ comments. Over the past two years I’ve gotten a LOT more concise with my .NET code. Lots of ? : statements and doing a lot more with the return statement.

    But, I don’t think I’d ever write a method to just check one var and return true / false. I’m assuming that’s just used for illustration. :)

    You can be concise in almost ANY language if you try hard enough. The trick is whether its worth it or not. While its not as concise your first example is a lot more readable to novice programmers. I don’t think I’d ever write an “if” for a true / false response, but in some cases being more verbose will help down the road. (Especially if you believe your code IS your documentation.)

    Like all things, we as developers we gotta pick the middle of the road solution and use our power wisely.

  16. Brian   February 16, 2009 @ 01:47 PM

    Thanks for letting us know about the funky rendering. Someone forgot a closing tag in his post…

  17. Arjun Rathore   March 12, 2009 @ 09:26 PM

    I really like the minimalistic approach of ROR. less is more!! For e.g. how the following rendering can be done in 1 line.

     <% for ad in @advertisements %>
        <%= render :partial => "ad", :locals => { :ad => ad } %>  
     <% end %>
    
     

    can be replaced by
     <%= render :partial => "ad", :collection => @advertisements %>