Question

Je sais que je pourrais facilement faire quelque chose comme

sub sin {
    sin($_[0]);
}

et symboliquement référence pour toutes les fonctions je dois ref symb, mais je voudrais juste savoir s'il y a un moyen de faire quelque chose comme

{$foo}(123);

vs.

&{$foo}(123);

qui fonctionne, mais pas pour les fonctions de base.

Merci.

Était-ce utile?

La solution

AFAIK non, vous ne pouvez pas le faire. Pour des raisons de performance, les fonctions de CORE ne regardent jamais la table des symboles une fonction équivalente SAUF SI de CORE::GLOBAL a été déclarée au moment de la compilation. Malheureusement, vous devez écrire cette fonction de CORE::GLOBAL et l'obtenir juste de simuler les conventions d'appel de la fonction réelle. Certaines fonctions CORE ne peuvent être entièrement reproduits sans hacks massif, print et open par exemple. Depuis CORE::GLOBAL est un effet global tout votre code et tout le code bibliothèque, vous devez être sûr de l'obtenir exactement droit ou cause très difficile à des erreurs de débogage. Certains modules, tels que autodie , doivent aller très loin pour envelopper autour des fonctions de base.

Mais ici, laissez-moi vous montrer où le casier des armes à feu et des munitions sont ...

my @return = eval "$function(\@args)";

... Bien sûr, cela est une sécurité massive et trou maintenabilité. Ne pas le faire.

Autres conseils

Si je lis cette question de SO correctement, vous ne pouvez pas prendre une référence à une fonction intégrée. Je soupçonne que des difficultés analogues vous empêchent d'invoquer Encastrements en utilisant des références symboliques.

En ce qui concerne l'utilisation de références symboliques au code Invoke, je suggère que vous utilisez une table d'expédition à la place. Par exemple:

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);

Il semble que vous devez remplacer les fonctions essentielles au moment de la compilation, et vous pouvez jouer avec eux. Je aime le hachage d'expédition (ou scalaire) approche mieux, cependant.

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";
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top