我想在一个类中动态定义方法。我正在编写一个跟踪器,比下面的骨架稍微复杂一些,它也可以感知状态,但这与我的问题无关。我用调用 sprintf 的跟踪方法编写了一个 TraceSlave 类,用文本 \n 替换换行符,一切都很好。
基本上我想将我的跟踪实例化为:
my @classes = qw(debug token line src match);
my $trace = Tracer->new(\@classes);
而且我应该能够将动态定义的跟踪方法称为:
$trace->debug("hello, world");
$trace->match("matched (%s)(%s)(%s)(%s)(%s)", $1, $2, $3, $4, $5);
所以我的 Tracer 类看起来像:
package Tracer;
sub new {
my $class = shift;
my $self = {};
my @traceClasses = @{$_[0]};
bless $self, $class;
for (@traceClasses) {
# This next line is wrong, and the core of my question
$self->$_ = new TraceSlave($_, ...)->trace
} # for (@traceClasses)
}
好吧,它不是因为那不编译。基本上我想定义 Tracer 实例的方法,作为 TraceSlave 实例的跟踪方法;在一个循环中。
我可以使用 AUTOLOAD 或 eval 来完成,但这是错误的。什么是正确的方法?
这是完整的 TraceSlave。没关系
package TraceSlave;
sub new {
my $self = { header => $_[1], states => $_[2], stateRef => $_[3] };
bless $self, $_[0];
return $self;
} # new()
sub trace {
my $self = shift;
my @states = @{$self->{states}};
if ($states[${$self->{stateRef}}]) { # if trace enabled for this class and state
my @args;
for (1..$#_) { ($args[$_-1] = $_[$_]) =~ s/\n/\\n/g; } # Build args for sprintf, and replace \n in args
print $self->{header}.sprintf($_[0], @args)."\n";
}
} # trace()