在“
Perl Best Practices”中,AUTOLOAD部分的第一行是:
Don’t use AUTOLOAD
然而,他描述的所有情况都是处理OO或模块.
我有一个独立的脚本,其中一些命令行开关控制哪些版本的特定功能被定义.现在我知道我可以把条件和evals,并把它们裸体放在我的文件的顶端,而不是其他的东西,但是我发现在文件末尾将它们放在AUTOLOAD中,方便而干净.
这是不好的习惯/风格吗?如果你觉得为什么,还有另一种办法呢?
按照布赖恩的要求
我基本上是使用它来进行基于命令行开关的条件编译.
我不介意一些建设性的批评.
sub AUTOLOAD { our $AUTOLOAD; (my $method = $AUTOLOAD) =~ s/.*:://s; # remove package name if ($method eq 'tcpdump' && $tcpdump) { eval q( sub tcpdump { my $msg = shift; warn gf_time()." Thread ".threads->tid().": $msg\n"; } ); } elsif ($method eq 'loginfo' && $debug) { eval q( sub loginfo { my $msg = shift; $msg =~ s/$CRLF/\n/g; print gf_time()." Thread ".threads->tid().": $msg\n"; } ); } elsif ($method eq 'build_get') { if ($pipelining) { eval q( sub build_get { my $url = shift; my $base = shift; $url = "http://".$url unless $url =~ /^http/; return "GET $url HTTP/1.1${CRLF}Host: $base$CRLF$CRLF"; } ); } else { eval q( sub build_get { my $url = shift; my $base = shift; $url = "http://".$url unless $url =~ /^http/; return "GET $url HTTP/1.1${CRLF}Host: $base${CRLF}Connection: close$CRLF$CRLF"; } ); } } elsif ($method eq 'grow') { eval q{ require Convert::Scalar qw(grow); }; if ($@) { eval q( sub grow {} ); } goto &$method; } else { eval "sub $method {}"; return; } die $@ if $@; goto &$method; }
解决方法
如果您使用AUTOLOAD的唯一原因是将块重新定位到最后,为什么不将其放在子程序的末尾,然后在定义其依赖变量时立即调用它?
sub tcpdump; # declare your subs if you want to call without parens # define the parameters compile(); # code that uses new subs sub compile { *tcpdump = $tcpdump ? sub { my $msg = shift; warn gf_time()." Thread ".threads->tid().": $msg\n"; } : sub {}; # ... } # EOF
更好的是,如果全局变量在其他地方不需要,只需传递值作为参数进行编译.