クラス内でメソッドを動的に定義したいと思います。以下のスケルトンよりもやや複雑なトレーサーを作成しています。これも状態を認識していますが、それは私の問題とは関係ありません。sprintf を呼び出し、改行をテキスト \n に置き換える trace メソッドを使用して TraceSlave クラスを作成しました。
基本的に、トレースを次のようにインスタンス化したいと思います。
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)
}
それはコンパイルされないからです。基本的には、TraceSlave のインスタンスの trace メソッドとして、Tracer インスタンスのメソッドを定義したいと考えています。ループで。
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()