in reply to while, foreach inside CGI.pm table

You can't execute arbitrary code while invoking a subroutine like that. You need to pass a string to the CGI.pm method, and it'll wrap it in a table.

I think this should work for you:

print table(Tr([ td( join "<br>\n", map { a({href => $urlhash{$_}}, $_) } keys %urlhash ) ]));