Wie rufe ich einen Funktionsnamen auf, der in einem Hash in Perl gespeichert ist?

Ich bin sicher, dass dies irgendwo in der Dokumentation behandelt wird, aber ich konnte es nicht finden ... Ich suche nach dem syntaktischen Zucker, der es ermöglicht, eine Methode für eine Klasse aufzurufen, deren Name in einem Hash gespeichert ist ( im Gegensatz zu einem einfachen Skalar):

use strict; use warnings;

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

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

Foo->$hash{func};

Wenn ich kopiere$hash{func} zuerst in eine skalare Variable, dann kann ich aufrufenFoo->$func ganz gut ... aber was fehlt zu aktivierenFoo->$hash{func} arbeiten?

(EDIT: Ich möchte nichts Besonderes tun, indem ich eine Methode für die Klasse aufrufeFoo - Dies könnte genauso gut ein gesegnetes Objekt sein (und in meinem aktuellen Code ist es das). Es war nur einfacher, ein in sich geschlossenes Beispiel mit einer Klassenmethode zu schreiben.)

EDIT 2: Der Vollständigkeit halber beziehe ich mich auf die folgenden Kommentare: Dies ist das, was ich gerade tue (dies ist in einer Bibliothek von Moose Attribut sugar, erstellt mitElch :: Exporteur):

# 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);
        },
    );
}

Ich habe die markierte Zeile oben durch Folgendes ersetzt:

        my $pk_accessor = $this->meta->find_attribute_by_name($args{primaryKey})->get_read_method_ref;
        my @args = ($args{primaryKey} => $this->$pk_accessor);

PS. Mir ist gerade aufgefallen, dass dieselbe Technik (Verwenden der Moose-Metaklasse, um das Coderef nachzuschlagen, anstatt die Namenskonvention anzunehmen)kann nicht auch für Prädikate verwendet werden, wieKlasse :: MOP :: Attribut hat kein ähnlichesget_predicate_method_ref Accessor. :(

Antworten auf die Frage(3)

Ihre Antwort auf die Frage