Perl 模块中 ref 函数的散列
Hash of ref functions inside Perl module
我正在尝试编写一个模块,它应该能够根据变量的内容调用特定的方法。我决定使用哈希将这些名称映射到函数引用。我已经编写了一些概念验证代码来查看这是否可行,但我在此过程中遇到了一些问题。
我遇到无法访问我的 $self->... 数据成员的引用函数调用问题。
下面是实际的复制粘贴概念验证示例,用于显示我遇到的问题。
#!/usr/bin/env perl
use strict;
use warnings;
package My::Test;
sub new {
my $class = shift;
my $self = {};
$self->{_currentType} = undef;
$self->{_currentData} = undef;
$self->{_mapping} = undef;
return bless $self, $class;
}
# Setup the mapping
sub createMapping {
my $self = shift;
my %mapping = ( 'mapping.1' => \&My::Test::handler1,
'mapping.2' => \&My::Test::handler2,
'mapping.3' => \&My::Test::handler3, );
$self->{_mapping} = \%mapping;
}
# This is the main entrypoint for actual processing where the appropriate handler function is invoked.
sub startMeUp {
my ($self, $mapType, $someDataToHandle) = @_;
$self->{_currentType} = $mapType;
$self->{_currentData} = $someDataToHandle;
# Now call this function
$self->{_mapping}->{$mapType}->();
}
# These functions below gets called, but the values of $self are not retained. Why?
sub handler1 {
my $self = shift;
print "I am a handler for $self->{_currentType}!\n";
}
sub handler2 {
my $self = shift;
print "I am a handler for $self->{_currentType}!\n";
}
sub handler3 {
my $self = shift;
print "I am a handler for $self->{_currentType}!\n";
}
sub manualFunction {
my $self = shift;
print "I am a manual call, I am $self->{_currentType}!\n";
}
1;
然后通过一个简单的调用脚本调用上面的模块,如下所示:
#!/usr/bin/env perl
use strict;
use warnings;
use My::Test;
my $test = My::Test->new();
$test->createMapping();
# We want to try to execute the handler2 function (mapping.2 is mapped to handler2 via createMapping).
# The function call works but when done this way, I cannot use
# $self->{someVariableName} to access module members as I'd like.
$test->startMeUp('mapping.2');
# The follow will work.
$test->manualFunction();
运行 perl 脚本产生以下结果:
% perl test.pl
Use of uninitialized value in concatenation (.) or string at My/Test.pm line 48.
I am a handler for !
I am a manual call, I am mapping.2!
我在寻找解决方案时遇到问题,为什么通过散列 table 调用引用的 startMeUp 函数不保留 中包含的值]$self->{这里有些class成员变量}.
我已尝试搜索有关此问题的 SO,但未能找到有关此特定问题的 question/answer。
我不确定我正在尝试做的事情在这种情况下是否根本不可能,或者我是否只是做错了,所以我希望你们中的一些人能指出我正确的方向。
(当然,只为三个元素实现这样的解决方案有点过分了,但在实际实现中会有更多元素,我宁愿避免编写一整屏的 if-elsif 语句,并且这也是一个很好的锻炼。
提前致谢!
此致,
克劳斯
如果您从
更改映射设置
sub createMapping {
my $self = shift;
my %mapping = ( 'mapping.1' => \&My::Test::handler1,
'mapping.2' => \&My::Test::handler2,
'mapping.3' => \&My::Test::handler3, );
$self->{_mapping} = \%mapping;
}
到
sub createMapping {
my $self = shift;
my %mapping = ( 'mapping.1' => sub { $self->handler1 } ,
'mapping.2' => sub { $self->handler2 } ,
'mapping.3' => sub { $self->handler3 } );
$self->{_mapping} = \%mapping;
}
您的测试脚本可以运行。
&My::Test::handler1
将调用 handler1
作为简单函数,而不是对象方法。
我正在尝试编写一个模块,它应该能够根据变量的内容调用特定的方法。我决定使用哈希将这些名称映射到函数引用。我已经编写了一些概念验证代码来查看这是否可行,但我在此过程中遇到了一些问题。
我遇到无法访问我的 $self->... 数据成员的引用函数调用问题。
下面是实际的复制粘贴概念验证示例,用于显示我遇到的问题。
#!/usr/bin/env perl
use strict;
use warnings;
package My::Test;
sub new {
my $class = shift;
my $self = {};
$self->{_currentType} = undef;
$self->{_currentData} = undef;
$self->{_mapping} = undef;
return bless $self, $class;
}
# Setup the mapping
sub createMapping {
my $self = shift;
my %mapping = ( 'mapping.1' => \&My::Test::handler1,
'mapping.2' => \&My::Test::handler2,
'mapping.3' => \&My::Test::handler3, );
$self->{_mapping} = \%mapping;
}
# This is the main entrypoint for actual processing where the appropriate handler function is invoked.
sub startMeUp {
my ($self, $mapType, $someDataToHandle) = @_;
$self->{_currentType} = $mapType;
$self->{_currentData} = $someDataToHandle;
# Now call this function
$self->{_mapping}->{$mapType}->();
}
# These functions below gets called, but the values of $self are not retained. Why?
sub handler1 {
my $self = shift;
print "I am a handler for $self->{_currentType}!\n";
}
sub handler2 {
my $self = shift;
print "I am a handler for $self->{_currentType}!\n";
}
sub handler3 {
my $self = shift;
print "I am a handler for $self->{_currentType}!\n";
}
sub manualFunction {
my $self = shift;
print "I am a manual call, I am $self->{_currentType}!\n";
}
1;
然后通过一个简单的调用脚本调用上面的模块,如下所示:
#!/usr/bin/env perl
use strict;
use warnings;
use My::Test;
my $test = My::Test->new();
$test->createMapping();
# We want to try to execute the handler2 function (mapping.2 is mapped to handler2 via createMapping).
# The function call works but when done this way, I cannot use
# $self->{someVariableName} to access module members as I'd like.
$test->startMeUp('mapping.2');
# The follow will work.
$test->manualFunction();
运行 perl 脚本产生以下结果:
% perl test.pl
Use of uninitialized value in concatenation (.) or string at My/Test.pm line 48.
I am a handler for !
I am a manual call, I am mapping.2!
我在寻找解决方案时遇到问题,为什么通过散列 table 调用引用的 startMeUp 函数不保留 中包含的值]$self->{这里有些class成员变量}.
我已尝试搜索有关此问题的 SO,但未能找到有关此特定问题的 question/answer。
我不确定我正在尝试做的事情在这种情况下是否根本不可能,或者我是否只是做错了,所以我希望你们中的一些人能指出我正确的方向。
(当然,只为三个元素实现这样的解决方案有点过分了,但在实际实现中会有更多元素,我宁愿避免编写一整屏的 if-elsif 语句,并且这也是一个很好的锻炼。
提前致谢!
此致, 克劳斯
如果您从
更改映射设置sub createMapping {
my $self = shift;
my %mapping = ( 'mapping.1' => \&My::Test::handler1,
'mapping.2' => \&My::Test::handler2,
'mapping.3' => \&My::Test::handler3, );
$self->{_mapping} = \%mapping;
}
到
sub createMapping {
my $self = shift;
my %mapping = ( 'mapping.1' => sub { $self->handler1 } ,
'mapping.2' => sub { $self->handler2 } ,
'mapping.3' => sub { $self->handler3 } );
$self->{_mapping} = \%mapping;
}
您的测试脚本可以运行。
&My::Test::handler1
将调用 handler1
作为简单函数,而不是对象方法。