How Old Are You?

Posted by Doug Thu, 05 Jan 2006 18:49:22 GMT

In one of my Ruby on Rails apps, I have a User class with a dob date of birth field. My client wants me to display the user’s age.

I had added this code a very long time ago:

def age
  (Date.today - self.dob).to_i / 365.25
end

I just went back and looked at that and was surprised I had let that code stand. It was just so smelly. I poked around and didn’t find any good helpers to clean it up. So, I started asking around to the Ruby smart-guys I know. Not to name drop, but Jim Weirich is a member of XP Cincinnati. When I asked him about it he responded with this paste

That demonstrates a lot of things I like about Jim. First, he’s a super friendly guy and very accessible. I don’t remember if he gave me his AIM nick or if it’s listed on his web site. Either way, he never acts bothered by my somewhat periodic interruptions about ruby related stuff. Second, he responded with code; not just code, but code with unit tests; not just simple unit tests, but fairly exhaustive unit tests. He was able to demonstrate with those tests why my algorithm wasn’t good enough; several of his tests failed with my code.

Jim practices what he preaches. He’s a big advocate for both Ruby and Test Driven Development. Even with this simple exercise he started off with good tests. Thanks Jim! I appreciate your help.

Posted in ,  | Tags ,  | 6 comments

Comments

  1. Lewis said about 18 hours later:

    There is a bug in the code.

    For example: dob = 1/1/2005 the day before is 12/31/2004

    so 2004 – 2005 = -1

    My birthday happens to be on the 1st of January :)

  2. Doug said about 20 hours later:

    Good catch! Although I don’t know that it’s a bug as much as just undefined. When I posed the question I never said what I wanted to happen with birthdays in the future. It could be argued that your age (given your birthday is in the future) is negative. :-) Ether way, I’ved added a result = 0 if result < 0 statement in age_in_years and these test cases:

        @born.dob=Date.parse("Jan 1, 2005")
        assert_equal 0, @born.age(Date.parse("Jan 2, 2005"))
        assert_equal 0, @born.age(Date.parse("Dec 31, 2005"))
        assert_equal 1, @born.age(Date.parse("Jan 2, 2006"))
        assert_equal 0, @born.age(Date.parse("Dec 31, 2004"))

    The format of these tests are a little different than Jim’s because of my environment.

  3. Jim Weirich said about 20 hours later:

    Hi Lewis,

    I don’t see a bug involving the first of January. In fact, I added this test case to make sure:

    def test_lewis_birthday
      born = Date.parse("Jan 1, 2005")
      assert_equal 0, age_in_years(born, born)
      assert_equal 0, age_in_years(born, Date.parse("Jan 2, 2005"))
      assert_equal 0, age_in_years(born, Date.parse("Dec 31, 2005"))
      assert_equal 1, age_in_years(born, Date.parse("Jan 1, 2006"))
    end

    If you are pointing out that asking for the age of someone who is not born yet (i.e. the today date is prior to the birth date) produces nonsensical output, then indeed it does.

    If defining age_in_years for that particular condition is important, one needs to decide what the proper outcome is (zero?, negative years?, exception?) and add the appropriate test cases.

    For myself, I should have stated that the precondition for age_in_years was that today >= born rather than leave it implicit in the tests.

    —Jim

  4. Lewis said about 20 hours later:

    Sorry, you guys are right, it’s not really a bug just undefined. The function totally works as written, it just when I ran it with my birthday, one of the tests failed.

    Maybe a test_lewis_birthday should be required on all date classes :)

    (or maybe not)

  5. Sean Smith said 6 days later:

    The paste is gone! That’s what I get for leaving readings for later….

  6. Christopher Jones said 3 months later:

    Anyone have the code from the paste. I thought I had found the answer to my problem but the paste is gone. Even archive.org does not have it.

    You can email me at the given address. Thanks.

Comments are disabled

Copyright 2001 - 2005 by Lathi.net and Doug Alcorn

Creative Commons, Some Rights Reserved Ruby on Rails Developer Powered by Debian GNU/Linux Powered by Typo