Rails contains a handy shortcut for adhering to The Principle of Least Knowledge. If your Person class has an address, and you want to get the person’s country, you can delegate it like so:

class Person < ActiveRecord::Base
  ...
  delegate :country, :to => :address
  ...
end

This is all well and good if you can be sure that there will always be an address for any given person. If address is nil and country is called, however, an exception will be raised (because nil.country is undefined).

Sometimes it’s helpful to be able to specify a default value, so I extended the delegate method to allow you to write:

class Person < ActiveRecord::Base
  ...
  delegate :country, :to => :address, :default => "United Kingdom" 
  ...
end

A word of caution however: use this with restraint. In general, default values should be stored in the database, not in your code. A next step for this might be for delegate to be association-aware, so that it can look up defaults from the database automatically when it encounters a nil object.

Here’s the code (mostly based on the current Rails implementation):

class Module
  def delegate(*methods)
    options = methods.pop
    unless options.is_a?(Hash) && to = options[:to]
      raise ArgumentError, "Delegation needs a target. Supply an options hash with a :to key as the last argument (e.g. delegate :hello, :to => :greeter)." 
    end

    methods.each do |method|
      if options.has_key? :default
        code = "(#{to} && #{to}.__send__(#{method.inspect}, *args, &block)) || #{options[:default].inspect}" 
      else
        code = "#{to}.__send__(#{method.inspect}, *args, &block)" 
      end

      module_eval(<<-EOS, "(__DELEGATION__)", 1)
        def #{method}(*args, &block)
          #{code}
        end
      EOS
    end
  end
end