Domanda

So che avrei potuto facilmente fare qualcosa di simile

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

e simbolicamente di riferimento che per ogni funzione che ho bisogno di Symb ref, ma mi piacerebbe solo sapere se c'è un modo per fare qualcosa di simile

{$foo}(123);

vs.

&{$foo}(123);

che funziona, ma non per le funzioni fondamentali.

Grazie.

È stato utile?

Soluzione

Per quanto ne sappia no, non puoi farlo. Per motivi di prestazioni, funzioni CORE mai guardare la tabella dei simboli a meno che una funzione di CORE::GLOBAL equivalente è stato dichiarato in fase di compilazione. Purtroppo, si deve scrivere quella funzione CORE::GLOBAL e farlo giusto per simulare le convenzioni di chiamata della funzione reale. Alcune funzioni CORE non possono essere interamente riprodotte senza hack massiccia, print e open per esempio. Dal momento che è globale CORE::GLOBAL un tutto il codice e tutto il codice libreria di effetti bisogna essere sicuri di ottenere che esattamente diritto o molto difficile da errori di debug. Alcuni moduli, come Autodie , andare a grandi lunghezze per avvolgere funzioni principali.

Ma qui, mi permetta di mostrare dove l'armadietto pistola e le munizioni sono ...

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

... Naturalmente, questo è un enorme sicurezza e manutenibilità foro. Non farlo.

Altri suggerimenti

Se leggo questa domanda SO correttamente, non si può prendere un riferimento a una funzione built-in. Ho il sospetto che le difficoltà analoghe vi impediranno di invocare built-in utilizzando i riferimenti simbolici.

Per quanto riguarda l'uso di riferimenti simbolici per il codice invoke, vorrei suggerire che si utilizza una tabella di spedizione, invece. Ad esempio:

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

Sembra che è necessario sostituire le funzioni di base in fase di compilazione, e poi si può giocherellare con loro. Mi piace l'hash spedizione (o scalare) approccio migliore, però.

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";
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top