¿Cómo puedo determinar si existe una función Perl en tiempo de ejecución?

StackOverflow https://stackoverflow.com/questions/433752

  •  10-07-2019
  •  | 
  •  

Pregunta

Estoy trabajando en un marco de prueba en Perl. Como parte de las pruebas, es posible que deba agregar verificaciones de precondición o poscondición para cualquier prueba dada, pero no necesariamente para todas ellas. Lo que tengo hasta ahora es algo como:

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

Desafortunadamente, esto genera " Subrutina indefinida & amp; generate_precondition_TEST1 llamado en ... " si la función no existe.

¿Cómo puedo determinar de antemano si existe la función, antes de intentar llamarla?

¿Fue útil?

Solución

Con definido:

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

EDITAR: hmm, solo pensé en evaluar como estaba en la pregunta, pero con referencias simbólicas planteadas con Leon Timmermans, ¿no podrías hacerlo?

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

incluso con estricto?

Otros consejos

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

o

*Package::Name::function{CODE}

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

o simplemente vive con la excepción. Si llama a la función en una evaluación y se establece $ @, entonces no puede llamar a la función.

Finalmente, parece que puede querer Test :: Class en lugar de escribir esto usted mismo.

Editar: define & amp; function_name (o la no estricta; definida & amp; {$ function_name} variante), como se menciona en las otras respuestas, parece ser la mejor manera. UNIVERSAL :: can es lo mejor para algo que va a llamar como método (estilísticamente), y por qué molestarse en jugar con la tabla de símbolos cuando Perl le da la sintaxis para hacer lo que quiere.

Aprendizaje ++ :)

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

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

Había usado el enfoque de Leon, pero cuando tuve varios paquetes, falló. No estoy seguro exactamente por qué; Creo que se relaciona con la propagación del alcance entre espacios de nombres. Esta es la solución que se me ocurrió.

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

Referencias:
__PACKAGE__ referencia en la página de perlmod.

Paquetes / __ PACKAGE__ referencia en Perl Training Australia.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top