Разве следующее не имеет больше смысла для HTML :: Template?
states => [ { id => 'AL', name => 'Alabama' }, ... ]
Это позволит вам использовать следующий шаблон:
<TMPL_LOOP NAME=states>
<TMPL_VAR NAME=name> (<TMPL_VAR NAME=id>)
</TMPL_LOOP>
Для этого выможет использовать следующее:
use List::Util 1.29 qw( pairmap );
states => [ pairmap { +{ id => $a, name => $b } } @states ]
Тем не менее, вы, вероятно, генерируете HTML.
<select name="state">
<TMPL_LOOP NAME=states>
<option value="<TMPL_VAR NAME=id_html>"><TMPL_VAR NAME=name_html></option>
</TMPL_LOOP>
</select>
Для этого вы можете использовать следующее:
use List::Util 1.29 qw( pairmap );
{
my %escapes = (
'&' => '&',
'<' => '<',
'>' => '>',
'"' => '"',
"'" => ''',
);
sub text_to_html(_) { $_[0] =~ s/([&<>"'])/$escapes{$1}/rg }
}
states => [ pairmap { +{ id_html => $a, name_html => $b } } map text_to_html, @states ]