Sometimes you gotta be explicit!

01 Jun 2013

In the spirit of keeping my code as concise as possible, in certain cases, I’ve started leaving off explicit “return” calls in my methods.

Earlier this week, however, I stumbled on a situation where it pays to be explicit.

I wanted to create a class instance method on a Person class that would return a particular person’s…particulars. That way my instance variables in a view could easily access someone’s details.

So, I went about my merry business on to what I thought would be a simple task.

Here’s the class (code that’s extraneous to the example has been omitted):

class Person
include Mongoid::Document

field :first_name, type: String
field :last_name, type: String
field :twitter_name, type: String
field :company, type: String
field :title, type: String
field :quote, type: String

def full_name
"#{first_name} #{last_name}"
end

end

OK, no big deal. I’ll just add a method called “details” to the class.

My logic was this: If a person has both a title and a company, return a string with those two bits of information. If a person is missing one of those bits, return a quote (if they have one). And finally, if they’ve got none of the above, just return an empty string.

Simple enough.

class Person
include Mongoid::Document

field :first_name, type: String
field :last_name, type: String
field :twitter_name, type: String
field :company, type: String
field :title, type: String
field :quote, type: String

def full_name
"#{first_name} #{last_name}"
end

def details
"#{title}, #{company}" unless title.blank? or company.blank?
"#{quote}" unless quote.blank?
""
end

end

To my surprise, “details” in its above implementation would return an empty string no matter what I tried. More specifically, it would return the last string in the method.

The following would return, as you might guess, “bar, yo!”

def details
"foo"
"#{title}, #{company}" unless title.blank? or company.blank?
"#{quote}" unless quote.blank?
"bar, yo!"
end

I eventually thought to try explicit return calls, and that’s when the method finally started working as expected.

def details
return "#{title}, #{company}" unless title.blank? or company.blank?
return "#{quote}" unless quote.blank?
return ""

# That last return is probably unnecessary, but after all
# of the preceding, I was going to give the method all the
# explicit returns it could handle. Plus, it's purdier.
end

So, long story short, continue being concise Ruby programmers. However, if you’re getting unexpected behavior, feel free to get explicit!