Object Oriented Parenting

Lessons in parenting from programming principles (or vice versa)

Tell, don’t ask

I have been working on a project Airship recently adopted, providing support and adding features. One of the new features brought me face to face with an impressively nested and contorted if-statement. I needed to inject some new logic somewhere in the thick of the sprawling tendrils of its conditionals. To respect the anonymity of this particular beast, we can approximate the complexity with the incredible logistics involved in getting packed for an outing with two tiny children, which, when simplified, might look something like this:

def pack_bag(children, destination, start, stop)
 bag = Bag.new
 children.each do |child|
  if stop - start > 1.hours || destination.distance > 5.miles
   if start.month > 10 || start.month < 3 || raining?
    if destination.outside?
     bag.add([hat, coat])
     if child.baby?
      bag.add([blanket, carrier])
     end
    end
   elsif start..stop.cover?(lunchtime)
    if child.baby?
     bag.add([carrier, diapers, wipes, baby_food, spoon])
    else
     bag.add([pb_j, apple]) unless destination.restaurant?
    end
   end
  end
 end

 if (daring? && willing_to_come_back_home?) || children.count < 1
  bag = nil
 end

 bag
end

Now, let’s add a new option. We could try “allow potty training”, or “allow optional toddler meltdown at random configuration”. It’s hard to know where to start. This code violates several basic Object-oriented Programming principles, including Tell, Don’t Ask.

The goal in programming as well as parenting would be to develop mature children objects that can perform their own functions.

def pack_bag(children, outing)
 bag = Bag.new
 children.each do |child|
  bag.add(child.pack_my_own_stuff(outing))
 end
end

But sometimes there are constraints on employing the Tell, Don’t Ask principle. Sometimes you’re not working with first-class, high level objects. Sometimes you’re given wee-little, wide-eyed hashes or chubby-cheeked, utterly dependent list of arguments to work with. In this case you need to take patient steps in the direction of Tell, Don’t Ask, but aware that you still need to provide thoughtful guidance.

Here are a few ideas to help you through the baby stages:

  1. Clarify your questions. Phrase the question so your toddler understands you. This helps you know what they are saying yes to, because children answer yes or no whether they really understand the question or not. Transform esoteric conditionals into English:

def coat_weather?(start)
 start.winter? || start.raining?
end

def winter?
 month > 10 || month < 3
end

2. Limit your questions. A good rule of thumb is to give your toddler 2 choices, both of which have outcomes you approve of. Factor by major distinctions:

pack_baby_bag if child.baby?
pack_toddler_bag if child.toddler?

3. Be explicit and concise about the behavior you are expecting. Provide sufficient and necessary instructions.

def pack_baby_bag
 pack_food
 pack_diapers
 pack_clothes
end

As with all parenting and programming advice, there’s no general solution that always works. Pay attention to what is developmentally appropriate for your situation. You don’t want to coddle badly written code and keep it from refactoring into responsible objects. On the other hand, don’t push your code to independence before it is ready.