Ist es möglich, einen Perl-Core-Modul symbolisch zu verweisen?
-
05-10-2019 - |
Frage
Ich weiß, dass ich einfach etwas tun könnte, wie
sub sin {
sin($_[0]);
}
und symbolisch Hinweis, dass für jede Funktion muss ich symb ref, aber ich möchte nur wissen, ob es einen Weg gibt so etwas wie
zu tun{$foo}(123);
vs.
&{$foo}(123);
, die aber nicht für die Kernfunktionen funktionieren.
Danke.
Lösung
AFAIK nein, man kann es nicht tun. Aus Performance-Gründen CORE
Funktionen schauen nie auf der Symboltabelle SOFERN eine äquivalente CORE::GLOBAL
Funktion wird bei der Kompilierung erklärt. Leider müssen Sie diese Funktion CORE::GLOBAL
schreiben und bekommen es nur Recht, die Aufrufkonventionen der realen Funktion zu simulieren. Einige CORE
Funktionen können nicht ganz ohne massive Hacks, print
und open
beispielsweise reproduziert werden. Da CORE::GLOBAL
global ist ein Effekt der gesamten Code und all Bibliotheks-Code müssen Sie sicher sein, um es zu bekommen genau Recht oder Ursache sehr schwer zu debuggen Fehler. Einige Module, wie zum Beispiel autodie , müssen große Anstrengungen unternehmen, um Kernfunktionen zu umwickeln.
Aber hier, lassen Sie mich Ihnen zeigen, wo die Waffe Schließfach und Munition sind ...
my @return = eval "$function(\@args)";
... natürlich ist dies eine massive Sicherheit und Wartbarkeit Loch. Tun Sie es nicht.
Andere Tipps
Wenn ich lesen Sie diese Frage SO korrekt, können Sie einen Verweis auf eine integrierte Funktion nicht übernehmen. Ich vermute, dass analoge Schwierigkeiten, die Sie von Aufrufen Einbauten mit symbolischen Referenzen verhindern.
Im Hinblick auf die Verwendung von symbolischen Verweis auf invoke Code, würde ich vorschlagen, dass Sie eine Dispatch-Tabelle verwenden statt. Zum Beispiel:
use strict;
use warnings;
sub sin_deg { sin $_[0] * atan2(1, 1) / 45 }
my %dt = (
sin_deg => \&sin_deg,
attack => sub { print "Attacking: @_\n" },
);
print $dt{sin_deg}->(60), "\n";
$dt{attack}->(1, 2, 3);
Es sieht aus wie Sie benötigen, um die Kernfunktionen bei der Kompilierung außer Kraft zu setzen, und dann können Sie mit ihnen Geige. Ich mag den Versand Hash (oder Skalar) nähern besser, though.
use strict;
use warnings;
our $s;
BEGIN {
*CORE::GLOBAL::sin= sub { sin($_[0])*2 };
*CORE::GLOBAL::cos= sub { cos($_[0])*2 };
our $s= *CORE::GLOBAL::sin;
}
*CORE::GLOBAL::sin= *CORE::GLOBAL::cos;
print sin(0.01)."\n";
print $s->(0.01)."\n";