class HTML { method _attr(Hash h) { h.keys.sort.map {|k| %Q' #{k}="#{h{k}}"' }.join('') } method _tag(Hash h, name, value) { "<#{name}" + self._attr(h) + '>' + value + "" } method table(Hash h, *data) { self._tag(h, 'table', data.join('')) } method table(*data) { self.table(Hash(), data...) } } class Table < HTML { method th(Hash h, value) { self._tag(h, 'th', value) } method th(value) { self.th(Hash(), value) } method tr(Hash h, *rows) { self._tag(h, 'tr', rows.join('')) } method tr(*rows) { self.tr(Hash(), rows...) } method td(Hash h, value) { self._tag(h, 'td', value) } method td(value) { self.td(Hash(), value) } } var header = %w(  X Y Z); var rows = 5; var html = HTML.new; var table = Table.new; say html.table( # attributes Hash( cellspacing => 4, style => "text-align:right; border: 1px solid;" ), # header table.tr(header.map{|elem| table.th(elem)}...), # rows (1..rows).map { |i| table.tr( table.td(:(align => 'right'), i), (header.len - 1).of { table.td(Hash(align => 'right'), 10000.rand.int) }... ) }... );