Schrift
[thread]7160[/thread]

caller() ueberlisten

Leser: 1


<< >> 7 Einträge, 1 Seite
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.
sri
 2005-07-26 03:33
#56686 #56686
User since
2004-01-29
828 Artikel
BenutzerIn
[Homepage] [default_avatar]
caller() ueberladen? :)
Strat
 2005-07-26 17:32
#56687 #56687
User since
2003-08-04
5246 Artikel
ModeratorIn
[Homepage] [default_avatar]
goto &sub
veraendert caller nicht... kannst du damit was machen? wird aber vermutlich haesslich
perl -le "s::*erlco'unaty.'.dk':e,y;*kn:ai;penmic;;print"
http://www.fabiani.net/
betterworld
 2005-07-26 22:16
#56688 #56688
User since
2003-08-21
2613 Artikel
ModeratorIn

user image
Mit goto kann ich zwar eine Funktion in caller() unsichtbar machen, aber ich wuesste nicht, wie ich das dazu nuetzen kann, eine beliebige Funktion einzufuegen...

sri: Ich weiß nicht ganz, wie ich es anstellen könnte, caller() zu überladen. So habe ich es probiert:
Code: (dl )
1
2
$ perl -wle 'sub CORE::caller {print "foo"} caller'
Useless use of caller in void context at -e line 1.
Scheint also nicht so ganz zu klappen. Vermutlich greift hier der Abschnitt aus perlsub:
Quote
Finally, some built-ins (e.g. "exists" or "grep") can't be overridden.
Selbst wenn ich caller() überladen könnte, wäre das eine recht haarige Angelegenheit. Nachdem der Ersatz-caller aufgerufen wird, müsste er sofort wieder das Original herstellen, damit weitere, von NEXT aufgerufene, Subroutinen nicht durcheinander kommen.
Update: mit CORE::GLOBAL::caller kann man es tatsaechlich ueberladen, wie pq mir gerade im IRC dankenswerterweise gesagt hat.

Naja, aber danke fuer die Antworten.\n\n

<!--EDIT|betterworld|1122407602-->
coax
 2005-07-26 22:57
#56689 #56689
User since
2003-08-11
457 Artikel
BenutzerIn
[default_avatar]
[quote=betterworld,26.07.2005, 20:16]sri: Ich weiß nicht ganz, wie ich es anstellen könnte, caller() zu überladen.[/quote]
Und wenn du vielleicht die betreffende NEXT-Methode ueberlaedst ?
,,Das perlt aber heute wieder...'' -- Dittsche
esskar
 2005-07-27 00:01
#56690 #56690
User since
2003-08-04
7321 Artikel
ModeratorIn

user image
Code: (dl )
BEGIN {*CORE::GLOBAL::caller = sub {print "foo"}} caller


;)
betterworld
 2005-07-27 00:54
#56691 #56691
User since
2003-08-21
2613 Artikel
ModeratorIn

user image
Ich hab jetzt bei den Monks eine gutaussehende Loesung gefunden:
http://perlmonks.org/?node_id=478344

coax: Hm, NEXT benutzt eigentlich Autoload. Naja, aber ich glaub, ich nehm die Loesung aus dem obigen Link.

Dank an alle Beteiligten.\n\n

<!--EDIT|betterworld|1122411321-->
<< >> 7 Einträge, 1 Seite



View all threads created 2005-07-26 02:23.