Perl 如何确保方法调用在正确的对象上使用正确的方法名称?
我正在编写一个程序,该程序会多次尝试处理,每次尝试时(之前/之后的其他几个步骤)都会存储到一个新日志中 而不是:Perl 如何确保方法调用在正确的对象上使用正确的方法名称?,perl,methods,Perl,Methods,我正在编写一个程序,该程序会多次尝试处理,每次尝试时(之前/之后的其他几个步骤)都会存储到一个新日志中 而不是: perl PerlLocalMethod.pl Entering into log 0: Processing 0 Entering into log 1: Processing 1 Entering into log 1: Processing 2 我认为问题在于,在我第一次调用Process方法时,Logger方法是“编译”的,我在第一次调用时使用了对象引用,但之后没有。 如
perl PerlLocalMethod.pl
Entering into log 0: Processing 0
Entering into log 1: Processing 1
Entering into log 1: Processing 2
我认为问题在于,在我第一次调用Process方法时,Logger方法是“编译”的,我在第一次调用时使用了对象引用,但之后没有。
如果我做了$logger->Print(),拼错了Print,并点击了一个我无法可靠测试的代码路径(这是针对嵌入式系统的,我不能强制每个错误条件),它会用一个未定义的方法错误输出脚本。我想我可以在logger中使用AUTOLOAD并记录任何错误的方法调用,但我想知道关于如何确保logger()调用可靠并使用正确对象的任何其他建议 在Perl中,子例程是在编译时编译的。将命名的子例程声明嵌入到子例程中不会达到预期效果,因此不建议这样做 如果你害怕打字错误,就编写测试。看看如何做。如果无法在开发人员机器上实例化系统特定的类,请使用模拟。或者使用较短的名称,如
P
您可以将最高范围内的记录器声明为$Logger上的闭包,您也需要在此处声明:
my $logger;
sub Logger { $logger->Print($_[0]) }
但是,如果有许多这样的变量和子例程,这会让人困惑,并且会导致代码更难维护。如果您在代码中使用了
使用警告,您会看到以下消息:
变量“$logger”不会在记录器第24行保持共享
这会提醒您注意这个问题(寓意是:始终使用严格的
和使用警告
)
我不完全清楚为什么您需要这么多级别的子例程来进行日志记录,但在我看来,所有将$logger
对象作为其第一个参数的子例程可能都应该通过MyLoggerObject
(它可能应该被称为MyLoggerClass
,因为它是一个类,而不是一个对象)
如果您这样做,那么您将得到以下代码(这似乎是您想要的):
哦,请注意,我已经从间接对象表示法调用(newclass(…)
)转移到稍微更安全的Class->new(…)
。您使用的样式在绝大多数情况下都有效,但如果不起作用,您将浪费数天时间试图解决问题。如上所述,在此类方法中使用词汇定义的变量是不可能的
如果你必须“管道胶带”解决这个问题,你可以使用全局变量(我们的而不是我的)
但是请注意,$logger和$thingToLog现在是可在此函数之外访问的全局变量。谢谢。我将研究mocking,我非常喜欢使用p.Plus Autoload至少记录错误调用的想法。要点(如果我理解的话)是为了在子例程名称中输入错误时获得编译时错误。在编译时不会检查方法。请始终使用use strict;使用warnings;
。这会对您有所帮助。
perl PerlLocalMethod.pl
Entering into log 0: Processing 0
Entering into log 1: Processing 1
Entering into log 1: Processing 2
my $logger;
sub Logger { $logger->Print($_[0]) }
use strict;
use warnings;
for my $i (0 .. 2) {
my $loggerObject = MyLoggerClass->new(tag => $i);
#.. do a bunch of other things ..
$loggerObject->Process($i);
#.. do a bunch of other things ..
}
package MyLoggerClass;
sub new {
my $package = shift;
my $self = { @_ };
return bless $self, $package;
}
sub Process {
my $self = shift;
my ($thingToLog) = @_;
$self->Logger("Processing $thingToLog");
}
sub Logger {
my $self = shift;
$self->Print($_[0]);
}
sub Print {
my $self = shift;
my ($value) = @_;
print "Entering into log $self->{tag}: $value\n";
}
1;
sub Process
{
our ($logger,$thingToLog) = @_;
sub Logger { $logger->Print($_[0]); }
Logger("Processing $thingToLog");
}