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.

War es hilfreich?

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";
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top