alias old_sprintf sprintf
alias old_printf printf

def sprintf format, *args
  format % args
end
def printf format, *args
  print format % args
end

class String
  alias old_percent %
  def % arg
    names = []
    target = gsub /(^|[^%])%(\w+):/ do
      name, space = $2, $1
      names << name unless names.include? name
      "#{space}%#{names.rindex(name) + 1}$"
    end
    args = case arg
      when Hash: names.map {|n| arg[n]}
      when Array: arg
      else [arg]
    end
    target.old_percent args
  end
end
