我确定文档中已经介绍了这个但我无法找到它...我正在寻找能够在名称存储在的类上调用方法的语法糖哈希(与简单标量相对):
use strict; use warnings;
package Foo;
sub foo { print "in foo()\n" }
package main;
my %hash = (func => 'foo');
Foo->$hash{func};
如果我先将$hash{func}
复制到标量变量中,那么我可以调用Foo->$func
就好......但是缺少什么来启用Foo->$hash{func}
?
(编辑:我并不是要通过调用类Foo
上的方法来做任何特别的事情 - 这可能很容易成为一个受祝福的对象(在我的实际代码中);它只是使用类方法更容易编写一个自包含的示例。)
编辑2:为了完整性,请回答下面的评论,这就是我实际做的事情(这是在Moose属性糖库中,用Moose::Exporter创建的):
# adds an accessor to a sibling module
sub foreignTable
{
my ($meta, $table, %args) = @_;
my $class = 'MyApp::Dir1::Dir2::' . $table;
my $dbAccessor = lcfirst $table;
eval "require $class" or do { die "Can't load $class: $@" };
$meta->add_attribute(
$table,
is => 'ro',
isa => $class,
init_arg => undef, # don't allow in constructor
lazy => 1,
predicate => 'has_' . $table,
default => sub {
my $this = shift;
$this->debug("in builder for $class");
### here's the line that uses a hash value as the method name
my @args = ($args{primaryKey} => $this->${\$args{primaryKey}});
push @args, ( _dbObject => $this->_dbObject->$dbAccessor )
if $args{fkRelationshipExists};
$this->debug("passing these values to $class -> new: @args");
$class->new(@args);
},
);
}
我用这个替换了上面标记的行:
my $pk_accessor = $this->meta->find_attribute_by_name($args{primaryKey})->get_read_method_ref;
my @args = ($args{primaryKey} => $this->$pk_accessor);
PS。我刚才注意到同样的技术(使用Moose元类查找coderef而不是假设其命名约定)也不能用于谓词,因为Class::MOP::Attribute没有一个类似的get_predicate_method_ref
访问者。 :(
答案 0 :(得分:14)
Foo->${\$hash{func}};
但为了清楚起见,我可能仍然把它写成:
my $method = $hash{func};
Foo->$method;
答案 1 :(得分:2)
您是否存储子例程名称而不是对代码的引用?
e.g。
use strict; use warnings;
package Foo;
sub foo { print "in foo()\n" }
package main;
my %hash = (func => \&Foo::foo);
$hash{func}->();
你不会传递课程名称,但如果这对你很重要,你可以使用类似的东西
my %hash = ( func => sub { return Foo->foo(@_) } );
答案 2 :(得分:1)
您是否尝试过UNIVERSAL's 可以方法?你应该能够实现这样的东西:
## untested
if ( my $code = $object->can( $hash{func} ) ) {
$object->$code();
}
我做了一个无用的单行示例来证明:
perl -MData::Dumper -le 'my %h = ( f => "Dump" ); my $o = Data::Dumper->new( [qw/1 2 3/] ); my $ref = $o->can( $h{f} ); print $o->$ref()'