How do you think CGI generates HTML output if not by printing it? And the documentation itself uses print in several examples (explicitly printing anchors, in fact).
It should take just a second to work out from the _tag_func sub in the code to work out that attributes for tag generation should be passed as a hashref followed by the contents.
$ perl -MCGI -E 'say CGI->new->a( {href => "http://example.com"}, "Sam
+ple" )'
<a href="http://example.com">Sample</a>
That being said in general it'd be better practice to use a templating engine for your HTML generation with that taking any dynamic values from whatever context its passed. If you look at Mojolicious and the like (Dancer2 (?), edit Dancer2::Template::TemplateToolkit specifically maybe) those use that kind of approach typically.
The cake is a lie.
The cake is a lie.
The cake is a lie.