Domanda

Sto lavorando a un framework di test in Perl. Come parte dei test, potrei aver bisogno di aggiungere controlli precondizione o postcondizione per ogni dato test, ma non necessariamente per tutti. Quello che ho finora è qualcosa di simile:

eval "&verify_precondition_TEST$n";
print $@ if $@;

Sfortunatamente, questo genera " Subroutine non definita & amp; confirm_precondition_TEST1 chiamato a ... " se la funzione non esiste.

Come posso determinare in anticipo se la funzione esiste, prima di provare a chiamarla?

È stato utile?

Soluzione

Con definito:

if (eval "defined(&verify_precondition_TEST$n)") {
    eval "&verify_precondition_TEST$n";
    print $@ if $@;
}
else {
    print "verify_precondition_TEST$n does not exist\n";
}

EDIT: hmm, ho solo pensato a eval com'era nella domanda, ma con riferimenti simbolici sollevati con Leon Timmermans, non puoi farlo

if (defined(&{"verify_precondition_TEST$n"}) {
    &{"verify_precondition_TEST$n"};
    print $@ if $@;
}
else {
    print "verify_precondition_TEST$n does not exist\n";
}

anche con rigoroso?

Altri suggerimenti

Package::Name->can('function')

o

*Package::Name::function{CODE}

# or no strict; *{ "Package::Name::$function" }{CODE}

o semplicemente vivere con l'eccezione. Se si chiama la funzione in un eval e $ @ è impostato, non è possibile chiamare la funzione.

Infine, sembra che potresti voler Test :: Class invece di scriverlo tu stesso.

Modifica: definito & amp; nome_funzione (o la variante non rigorosa; definita & amp; {$ nome_funzione} ), come menzionato nelle altre risposte, sembra essere la miglior modo. UNIVERSAL :: can è la cosa migliore per qualcosa che chiamerai come metodo (stilisticamente), e perché preoccuparsi di fare casino con la tabella dei simboli quando Perl ti dà la sintassi per fare quello che vuoi.

Apprendimento ++ :)

sub function_exists {    
    no strict 'refs';
    my $funcname = shift;
    return \&{$funcname} if defined &{$funcname};
    return;
}

if (my $subref = function_exists("verify_precondition_TEST$n") {
    ...
}

Avevo usato l'approccio di Leon, ma quando avevo più pacchetti fallì. Non sono sicuro del perché; Penso che si riferisca alla propagazione dell'ambito tra gli spazi dei nomi. Questa è la soluzione che mi è venuta in mente.

my %symbols = ();
my $package =__PACKAGE__; #bring it in at run-time
{
    no strict;
    %symbols = %{$package . "::"}; #See Symbol Tables on perlmod
}
print "$funcname not defined\n" if (! defined($symbols{$funcname});

Riferimenti:
__PACKAGE__ riferimento nella pagina perlmod.

Pacchetti / __ PACCHETTO__ di riferimento su Perl Training Australia.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top