use Interpolation; tie %HTML, "Interpolation", \&escape; # works with global or with lexical: my %HTML { my %esc; BEGIN { %esc = ( '&' => '&', '<' => '<', '>' => '>', '"' => '"', # if you want them ); } sub escape { my $s = pack 'U0a*', shift; $s =~ s/([&<>"])/$esc{$1}/g; $s =~ s/([^\0-\x7F])/$esc{$1} ||= '&#' . ord($1) . ';'/ge; return $s; } }