我正在查看 perl 代码,我看到了这个:
sub html_filter {
my $text = shift;
for ($text) {
s/&/&/g;
s/</</g;
s/>/>/g;
s/"/"/g;
}
return $text;
}
在这种情况下 for 循环会做什么,为什么要这样做?
该for
循环将列表中每个元素的别名,其循环到$_
。在这种情况下,只有一个元素,$text
。
在体内,这允许人们写
s/&/&/g;
等等,而不必写
$text =~ s/&/&/g;
反复。另请参阅perldoc perlsyn。
如果没有显式循环变量,则for
循环使用名为 的特殊变量$_
。循环内的替换语句也使用特殊$_
变量,因为没有指定其他变量,所以这只是使源代码更短的一个技巧。我可能会把这个函数写成:
sub html_filter {
my $text = shift;
$text =~ s/&/&/g;
$text =~ s/</</g;
$text =~ s/>/>/g;
$text =~ s/"/"/g;
return $text;
}
这不会对性能产生影响,并且 Perl 以外的人都可以阅读。
正如 Hewgill 先生所指出的,代码示例隐含地本地化和别名为神奇的隐含变量 $_。
他以样板代码为代价提供了一种更具可读性的替代品。
没有理由为了简洁而牺牲可读性。只需用显式版本替换隐式本地化和赋值:
sub html_filter {
local $_ = shift;
s/&/&/g;
s/</</g;
s/>/>/g;
s/"/"/g;
return $_;
}
如果我不太了解 Perl 并且遇到了这段代码,我会知道我需要查看文档,$_
并且-- 作为奖励,这里有一些local
localizing 的示例。perlvar
$_
对于经常使用 Perl 的人来说,上面的内容应该很容易理解。
所以这里真的没有理由为了简洁而牺牲可读性。
它只是用于将 $text 别名为默认变量 $_。完成是因为他们懒得使用显式变量,或者不想浪费宝贵的周期来创建新的标量。
它清理 &、<、> 和引号字符,并用适当的 HTML 实体字符替换它们。
它循环遍历您的文本,并用 &、< 和 <、> 用 > 和 " 用 " 替换与符号 (&)。你会这样做以输出到 .html 文档......这些是正确的实体字符。
通过使用 wantarray 来测试所需的上下文,原始代码可以更加灵活:
sub html_filter {
my @text = @_;
for (@text) {
s/&/&/g;
s/</</g;
s/>/>/g;
s/"/"/g;
}
return wantarray ? @text: "@text"; }
这样您就可以在列表上下文或标量上下文中调用它并返回正确的结果,例如:
my @stuff = html_filter('"','>');
print "$_\n" for @stuff;
my $stuff = html_filter('&');
print $stuff;