我正在开发一个程序,该程序会多次尝试处理,每次尝试时都会存储到新日志(之前/之后的其他几个步骤)。
use strict;
for (my $i = 0; $i < 3; $i++)
{
my $loggerObject = new MyLoggerObject(tag => $i);
#.. do a bunch of other things ..
Process($loggerObject,$i);
#.. do a bunch of other things ..
}
sub Process
{
my ($logger,$thingToLog) = @_;
sub Logger { $logger->Print($_[0]); }
Logger("Processing $thingToLog");
}
package MyLoggerObject;
sub new
{
my $package = shift;
my %hash = (@_); my $self = \%hash;
return bless $self, $package;
}
sub Print
{
my $self = shift;
my $value = shift;
print "Entering into log ".$self->{tag}.": $value\n";
}
1;
为了避免不得不做一堆 $self->{logger}->Print() 和拼错 Print 的风险,我试图将它们折叠到本地子例程中,如上所示。但是,当我运行它时,我得到:
perl PerlLocalMethod.pl
Entering into log 0: Processing 0
Entering into log 0: Processing 1
Entering into log 0: Processing 2
代替:
perl PerlLocalMethod.pl
Entering into log 0: Processing 0
Entering into log 1: Processing 1
Entering into log 1: Processing 2
我假设问题是 Logger 方法在我第一次使用我在第一次调用时使用的对象引用调用 Process 方法时被“编译”,但之后没有。 如果我执行了 $logger->Print(),拼写错误的 Print,并命中了一个我无法可靠测试的代码路径(这是针对嵌入式系统的,我无法强制执行每个错误条件),它会导致脚本出现未定义的错误方法。我想我可以在记录器中使用 AUTOLOAD 并记录任何错误的方法调用,但我想知道关于如何确保我的 Logger() 调用可靠并使用正确对象的任何其他建议。
最佳答案
在 Perl 中,子例程是在编译时编译的。将命名的子例程声明嵌入到子例程中并不能达到预期的效果,因此不推荐这样做。
如果你害怕错别字,写测试。参见 Test::More关于如何去做。如果您无法在开发机器上实例化系统特定类,请使用模拟。或者使用更短的名称,例如 P
。
您可以在最高范围内将 Logger 声明为 $logger 的闭包,您也需要在那里声明:
my $logger;
sub Logger { $logger->Print($_[0]) }
但如果有很多这样的变量和子例程,这会造成混淆并导致代码更难维护。
关于perl - 如何确保我的方法调用在正确的对象上使用正确的方法名称?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62345221/