A short but hopefully sweet solution:
#!/usr/bin/env ruby
require 'enumerator'
require 'optparse'
rule = 110
steps = 20
cells = 1
OptionParser.new do |opts|
opts.on("-r RULE", Integer) {|rule|}
opts.on("-s STEPS", Integer) {|steps|}
opts.on("-c CELLS", Integer) {|cells|}
end.parse!
cells = cells.to_s(2)
steps.times do
puts cells.gsub('0', ' ').gsub('1', 'X')
cells = "00#{cells}00".split(//).enum_for(:each_cons, 3)
cells = cells.map {|neighborhood|
rule[neighborhood.join.to_i(2)] }.join
end