我正在寻找有关Perl最佳实践的建议.我写了一个脚本,它有一个复杂的正则表达式:
my $regex = qr/complicated/;
# ...
sub foo {
# ...
if (/$regex/)
# ...
}
Run Code Online (Sandbox Code Playgroud)
where foo是一个经常被调用的函数,并且$regex不在函数之外使用.处理这种情况的最佳方法是什么?我只希望它被解释一次,因为它漫长而复杂.但是将它放在全球范围内似乎有点可疑,因为它仅用于该子目录.是否有合理的方法将其声明为静态?
另一个可能不合理的全球性问题也出现了类似的问题.它读取当前日期和时间并适当地格式化它.这也被多次使用,并且仅在一个功能中使用.但是在这种情况下更重要的是它不能重新初始化,因为我希望日期时间的所有实例在给定的脚本调用中是相同的,即使在执行期间分钟翻转.
目前我有类似的东西
my ($regex, $DT);
sub driver {
$regex = qr/complicated/;
$DT = dateTime();
# ...
}
# ...
driver();
Run Code Online (Sandbox Code Playgroud)
至少略微隔离它.但也许有更好的方法.
再说一遍:我正在寻找正确的方法,以遵循最佳实践和Perl习语.性能很好,但如果我不能拥有所有东西,那么可读性和其他需求就会优先考虑.
hob*_*bbs 25
如果您使用的是perl 5.10+,请使用state变量.
use feature 'state';
# use 5.010; also works
sub womble {
state $foo = something_expensive();
return $foo ** 2;
}
Run Code Online (Sandbox Code Playgroud)
只会打something_expensive一次电话.
如果你需要使用旧的perls,那么在外部作用域中使用一个词法变量,并使用一对额外的大括号:
{
my $foo = something_expensive();
sub womble {
return $foo ** 2;
}
}
Run Code Online (Sandbox Code Playgroud)
这$foo不会泄漏给除了之外的任何人womble.
ike*_*ami 15
模式中是否有插值?如果不是,则无论qr //执行多少次,模式都只会被编译一次.
$ perl -Mre=debug -e'qr/foo/ for 1..10' 2>&1 | grep Compiling | wc -l
1
$ perl -Mre=debug -e'qr/foo$_/ for 1..10' 2>&1 | grep Compiling | wc -l
10
Run Code Online (Sandbox Code Playgroud)
即使存在插值,只有在插值变量发生变化时才会编译模式.
$ perl -Mre=debug -e'$x=123; qr/foo$x/ for 1..10;' 2>&1 | grep Compiling | wc -l
1
$ perl -Mre=debug -e'qr/foo$_/ for 1..10' 2>&1 | grep Compiling | wc -l
10
Run Code Online (Sandbox Code Playgroud)
否则,你可以使用
{
my $re = qr/.../;
sub foo {
...
/$re/
...
}
}
Run Code Online (Sandbox Code Playgroud)
要么
use feature qw( state );
sub foo {
state $re = qr/.../;
...
/$re/
...
}
Run Code Online (Sandbox Code Playgroud)