Here's the solution I came up with before submitting this idea:

# spiral.rb
# RubyQuiz #109
# Bob Showalter

class Integer

  def odd?
    self % 2 == 1
  end

end

class Spiral

  # order must be > 0
  def initialize(order)
    raise ArgumentError, "order must be > 0" unless order.to_i > 0
    @order = order
  end

  # writes the spiral to stdout
  def output
    puts "\n"
    0.upto(@order - 1) do |r|
      row_for(@order, r)
      puts "\n\n"
    end
  end

  private

  # emits row r for spiral of order p
  def row_for(p, r)
    if p <= 1
      cell(0)
    elsif p.odd?
      if r == p - 1
        row(p)
      else
        row_for(p - 1, r)
        col(p, r)
      end
    else
      if r == 0
        row(p)
      else
        col(p, r)
        row_for(p - 1, r - 1)
      end
    end
  end

  # emits the full row (top or bottom) for spiral of order p
  def row(p)
    x = p * (p - 1)
    y = x + p - 1
    x.upto(y) {|i| cell(p.odd? ? x - i + y : i) }
  end

  # emits the single column cell for row r of spiral of order p
  def col(p, r)
    x = p * (p - 1)
    r = p - r - 1 if p.odd?
    cell(x - r)
  end

  # emits a single cell
  def cell(i)
    printf ' %3d ', i
  end

end

n = (ARGV.first || 3).to_i
Spiral.new(n).output