如何调用存储在 Perl 哈希中的函数名称? [英] How do I call a function name that is stored in a hash in Perl?

查看:24
本文介绍了如何调用存储在 Perl 哈希中的函数名称?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我确定这在某处的文档中有所介绍,但我一直无法找到它...我正在寻找语法糖,它可以在名称存储在的类上调用方法哈希(相对于简单的标量):

I'm sure this is covered in the documentation somewhere but I have been unable to find it... I'm looking for the syntactic sugar that will make it possible to call a method on a class whose name is stored in a hash (as opposed to a simple scalar):

use strict; use warnings;

package Foo;
sub foo { print "in foo()
" }

package main;
my %hash = (func => 'foo');

Foo->$hash{func};

如果我首先将 $hash{func} 复制到一个标量变量中,那么我可以调用 Foo->$func 就好了......但是缺少什么让 Foo->$hash{func} 工作?

If I copy $hash{func} into a scalar variable first, then I can call Foo->$func just fine... but what is missing to enable Foo->$hash{func} to work?

(我并不是要通过调用类 Foo 上的方法来做任何特别的事情——这很容易成为一个受祝福的对象(在我的实际代码中它是);使用类方法编写一个独立的示例更容易.)

( I don't mean to do anything special by calling a method on class Foo -- this could just as easily be a blessed object (and in my actual code it is); it was just easier to write up a self-contained example using a class method.)

编辑 2:为了完整起见下面的评论,这就是我实际在做的事情(这是在 Moose 属性糖库中,使用 Moose::Exporter):

EDIT 2: Just for completeness re the comments below, this is what I'm actually doing (this is in a library of Moose attribute sugar, created with 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);
        },
    );
}

我已将上面的标记行替换为:

I've replaced the marked line above with this:

        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 访问器.:(

PS. I've just noticed that this same technique (using the Moose meta class to look up the coderef rather than assuming its naming convention) cannot also be used for predicates, as Class::MOP::Attribute does not have a similar get_predicate_method_ref accessor. :(

推荐答案

Foo->${$hash{func}};

但为了清楚起见,我可能仍将其写为:

But for clarity, I'd probably still write it as:

my $method = $hash{func};
Foo->$method;

这篇关于如何调用存储在 Perl 哈希中的函数名称?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆