Thread caller() ueberlisten (6 answers)
Opened by betterworld at 2005-07-26 02:23

betterworld
 2005-07-26 02:23
#56685 #56685
User since
2003-08-21
2613 Artikel
ModeratorIn

user image
Hallo,

gibt es eine Möglichkeit, das aktuelle Paket und die aktuelle Subroutine auf einen zur Kompilierzeit unbekannten Wert (sprich eine Variable) zu setzen, mit der Absicht, dass caller() diese Werte zurueckgibt?

Genauer gesagt geht es mir darum, einem beliebigen Paket zur Laufzeit eine Subroutine zu injizieren, die NEXT verwendet, wie das untenstehende Beispiel zeigt:
Code: (dl )
1
2
3
4
5
6
7
8
use NEXT;

no strict 'refs';
*{$paket . '::function'} = sub {
my $this = shift;
# do something
$this->NEXT::function(@_);
};

Dieser Code funktioniert nicht wie gewuenscht, weil NEXT die aufrufende Funktion mit caller(1) bestimmt, und das ergibt leider nicht ${paket}::function, sondern das den vollqualifizierten Namen der Subroutine, in dem der obige Code steht.

Man kann das auch mit dem folgenden Script noch einmal ueberpruefen:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
sub printcaller {
my $caller = (caller(1))[3];
print "$caller\n";
}

my $paket = "testpaket";
*{$paket.'::function'} = sub {
printcaller();
};

testpaket::function();

Die Ausgabe ist main::_ _ANON_ _, aber ich moechte gerne, dass es testpaket::function ist.

Eine moegliche Loesung waere die Benutzung von eval, aber das will ich eigentlich nicht:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
sub printcaller {
my $caller = (caller(1))[3];
print "$caller\n";
}

my $paket = 'testpaket';

eval qq{
sub ${paket}::function {
printcaller();
}
};

testpaket::function(); # Ausgabe: testpaket::function


Weiß jemand eine andere Lösung?
Danke.

View full thread caller() ueberlisten