Perl 5.10 and above have state variables, but they don't work for hashes and arrays - just scalars. Still, you can use hashrefs/arrayrefs.
sub encode { state $lookup = { '"' => '"', '&' => '&', '<' => '<', '>' => '>', map((chr($_), "&#$_;"), (0..31)), }; state $re = do { my $tmp = join('', keys %$lookup); qr/([$tmp])/ } +; my ($text) = @_; return '' unless defined $text; $text =~ s/$re/$lookup->{$1}/g; return $text; }
If you need to support older versions of Perl, then curly braces can be used to limit the scope of lexical variables...
{ my $lookup = { '"' => '"', '&' => '&', '<' => '<', '>' => '>', map((chr($_), "&#$_;"), (0..31)), }; my $re = do { my $tmp = join('', keys %$lookup); qr/([$tmp])/ }; sub encode { my ($text) = @_; return '' unless defined $text; $text =~ s/$re/$lookup->{$1}/g; return $text; } }
Or even better (because it delays populating the variables until they're needed):
{ my ($lookup, $re); sub encode { $lookup ||= { '"' => '"', '&' => '&', '<' => '<', '>' => '>', map((chr($_), "&#$_;"), (0..31)), }; $re ||= do { my $tmp = join('', keys %$lookup); qr/([$tmp])/ } +; my ($text) = @_; return '' unless defined $text; $text =~ s/$re/$lookup->{$1}/g; return $text; } }
In reply to Re: Best Practice for replace sub
by tobyink
in thread Best Practice for replace sub
by Skeeve
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |