# need '*table' and '*Tr' in order to use start_table() and start_Tr() use CGI qw( :standard *table *Tr ); # ... # note the map() calls each represent a nested for() loop # and further that passing an array reference to td() creates a set of blocks, one per element of the referenced array print join( "\n", start_table, start_Tr, (map { map { td($_) } @$_ } @$db_results), end_Tr, end_table ), "\n";