Ich bin sicher, dass dies in der Dokumentation irgendwo abgedeckt ist, aber ich konnte es nicht finden ... Ich bin auf der Suche nach dem syntaktischen Zucker, der es möglich macht, eine Methode für eine Klasse aufzurufen, deren Name in einem gespeichert ist Hash (im Gegensatz zu einer einfachen skalaren gegen):Wie rufe ich einen Funktionsnamen auf, der in Perl in einem Hash gespeichert ist?
use strict; use warnings;
package Foo;
sub foo { print "in foo()\n" }
package main;
my %hash = (func => 'foo');
Foo->$hash{func};
Wenn ich $hash{func}
in eine skalare Variable zuerst kopieren, dann kann ich Foo->$func
ganz gut nennen ... aber was Foo->$hash{func}
zu ermöglichen fehlt zu arbeiten?
(EDIT: Ich möchte nicht etwas Besonderes tun, indem eine Methode auf Klasse Foo
aufrufen - das könnte genauso gut ein gesegnetes Objekt sein (und in meinem eigentlichen Code ist es), es war einfach einfacher zu schreiben ein eigenständiges Beispiel mit einer Klassenmethode.)
EDIT 2: Nur zur Vollständigkeit der Kommentare unten, das ist, was ich eigentlich tue (dies ist in einer Bibliothek von Moose Attribut Zucker, erstellt mit 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: [email protected]" };
$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 mit dieser Fassung:
my $pk_accessor = $this->meta->find_attribute_by_name($args{primaryKey})->get_read_method_ref;
my @args = ($args{primaryKey} => $this->$pk_accessor);
PS. Ich habe gerade bemerkt, dass die gleiche Technik (mit der Moose Meta-Klasse, um die coderef nachschlagen, anstatt seine Namenskonvention vorausgesetzt) kann nicht auch für Prädikate verwendet werden, wie Class::MOP::Attribute hat keine ähnliche get_predicate_method_ref
Accessor. :(
Ich glaube nicht, dass möglich ist, aufgrund der Perl-Parsing-Reihenfolge. Warum willst du $ hash {func} nicht zuerst in einen Skalar kopieren? –
Kein besonderer Grund, außer es scheint unnötig, und dies war ein interessantes Puzzle, das mich ratlos. Ich glaubte das nicht einfach, weil ich die Antwort nicht wusste, dass es keine Antwort gab. :) (tl; dr-version: weil ich neugierig bin!) – Ether
Äh, mir scheint, wenn du Elch benutzt, dann gehst du immer noch in die falsche Richtung. Eine der Eigenschaften von Moose ist das Meta-Objektmodell, auf dem es aufgebaut ist ... Ich habe das Gefühl, dass es eine Methode gibt, die man aufrufen kann, um den tatsächlichen Namen nach Zeichenfolgen zu suchen, den man dann aufrufen könnte, statt blanke Zeichenfolgen zu verwenden . Ich weiß es nicht von ganz oben, obwohl ... –