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

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

问题描述

我敢肯定,这是覆盖的地方在文档中,但我一直无法找到它......我要找的语法糖,这将使它可以调用的方法在一个类,其名称存储在散列(而不是一个简单的标量):

 使用严格的;使用警告;包富;
子富{打印,在富()\\ n}包为主;
我的哈希%=(FUNC =>'富');Foo-> $ {哈希FUNC};

如果我复制 $哈希{FUNC} 成标量第一,那么我可以叫 Foo-> $ FUNC 就好了...但遗失,使 Foo-> $ {哈希FUNC} 工作

(编辑:我的意思不是通过调用在类中的方法做什么特别的东西 - 这也很容易成为一个祝福的对象(在我实际code这是);使用一个类的方法写了一个自包含的例子,这只是更容易)

编辑2:只是为了完整性再下面的意见,这是我实际上做什么(这是驼鹿库属性糖,用的穆斯::出口商):

 #增加一个访问到同级模块
子foreignTable
{
    我($元,$表,%参数)= @_;    我的$类='MyApp的::方向1 ::方向2 ::。 $表;
    我的$ dbAccessor ​​= lcfirst $表;    EVAL需要$班还是死{无法加载$类:$ @};    $荟萃> ADD_ATTRIBUTE(
        $表,
        是= GT; RO,
        ISA => $类,
        init_arg =>民主基金,#不允许在构造函数
        懒惰=> 1,
        predicate => '具有_' 。 $表,
        默认=>子{
            我的这个$ =转变;
            $这个 - >调试(在建设者为$类);            ###这是一个使用散列值作为方法名行
            我@args =(的$ args {}的PrimaryKey = GT; $这个 - > $ {\\ $ {ARGS的PrimaryKey}});
            推@args,(_dbObject => $这个 - > _dbObject-> $ dbAccessor)
                如果的$ args {fkRelationshipExists};            $这个 - >调试(传递这些值$类 - >新建:@args);
            $课堂>新建(@args);
        },
    );
}

我把它换成上面这个标记行:

 我的$ pk_accessor ​​= $这个 - >荟萃> find_attribute_by_name(的$ args {}的PrimaryKey) -  GT; get_read_method_ref;
        我@args =(的$ args {}的PrimaryKey = GT; $这个 - > $ pk_accessor);

PS。我刚刚注意到,同样的技术(使用穆斯元类来查找codeREF,而不是假设它的命名约定)的无法的也可用于predicates,如<一个HREF =htt​​p://search.cpan.org/perldoc?Class%3a%3aMOP%3a%3aAttribute相对=nofollow>类:: MOP ::属性没有类似的get_ predicate_method_ref 访问。 (


解决方案

  Foo-&GT; $ {\\ $ {哈希FUNC}};

但为了清楚起见,我可能还在写为:

 我的$方法= $ {哈希FUNC};
Foo-&GT; $方法;

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()\n" }

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

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?

(EDIT: 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.)

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. 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天全站免登陆