Nasty Age Printing Method I have this ugly age printing method. Can you do better?

def age(birth_date)
  today = Date.today
  years = today.year - birth_date.year
  months = today.month - birth_date.month
  (months -1) if today.day &lt; birth_date.day
  if years == 0 &amp;&amp; months == 1
    age =  "#{months} month"
  elsif years == 0 &amp;&amp; months &gt; 1
    age =  "#{months} months"
  elsif years &gt; 0 &amp;&amp; months &gt; 0
    age = years == 1 ? "1 year, #{months} months" : "#{years} years, #{months} months"
  elsif years &gt; 0 &amp;&amp; months &lt; 0
    months = months + 12
    years = years - 1
    age = "#{months} months" if years == 0
    age = "1 year, #{months} months" if years == 1
    age = "#{years} years, #{months} months" if years == 1
  end
  age
end
Some notes:


(months -1) if today.day &lt; birth_date.day. Note that this is doing nothing, months - 1 is evaluated and dropped.
There is a age = in every branch of the conditional, and finally age is returned. That's unnecessary and not idiomatic, in Ruby conditionals are expressions, so we don't need to create a variable. 
About this:

age = "#{months} months" if years == 0
age = "1 year, #{months} months" if years == 1


It's preferable not to use in-line conditionals when you are dealing with assignments or expressions (it's ok if you are performing side-effects, i.e. fail("error") if x &lt; 0). In general follow functional programming guidelines, specially when dealing with logic (if you do some programming that does not deal with logic, please let me know ;-)). It should look (you could also use a case) something like this:

age = if years == 0
  "#{months} months"
elsif years == 1
  #{months} months" if years == 1
...
end



I'd write:

def age(birth_date)
  today = Time.zone.today
  total_months = (today.year*12 + today.month) - (birth_date.year*12 + birth_date.month)
  years, months = total_months.divmod(12)
  strings = [[years, "year"], [months, "month"]].map do |value, unit|
    value &gt; 0 ? [value, unit.pluralize(value)].join(" ") : nil
  end
  strings.compact.join(", ")
end


Note that, to keep it simple, this code (as yours) ignores the day of the month, which gives a slightly wrong answer.