Ponteiros de função são úteis quando precisamos ou desejamos dar um mesmo tratamento para funções ou métodos distintos. Seu uso é bastante difundido dentre programadores C/C++, o que ajuda na organização e reusabilidade de código, facilitando o gerenciamento de erros.
Em geral, programadores iniciantes costumam “fugir” dos ponteiros, porém, após uma compreensão de seu funcionamento básico, é possível perceber a sua empregabilidade em várias situações.
Neste rápido post, tentarei exemplificar o uso de ponteiros de função em PERL.
Como não definimos um tipo ao criar uma variável em PERL, basta adicionarmos uma variável qualquer, recebendo o nome da função que desejamos, e depois invocá-la, conforme exemplo abaixo:
#!/usr/bin/perl use strict; # Comentar esta linha para rodar o primeiro exemplo sub hello_world { print "Hello World!!\n"; } sub call_function { my $function = shift; print "Invocando Funcao\n"; &{$function}(); print "Pronto!\n"; } call_function("hello_world");
Perceba que apenas foi passado uma “string” para “call_function” contendo o nome da função desejada.
Até então vimos o quão fácil é invocar uma função através de um “ponteiro” para ela. O ponteiro não está explícito no código, porém, podemos perceber que através do “&” estamos referenciando o símbolo (função) referente a string passada.
Agora, se estivermos usando a diretiva “strict”, não poderemos trabalhar neste simples formato, pois o interpretador retornará o seguinte erro:
Can’t use string (“hello_world”) as a subroutine ref while “strict refs” in use at pointer.pl line 13.
Este problema ocorre pois, através da diretiva “strict”, todas as variáveis e funções utilizadas no script devem ser definidas no momento do seu carregamento. E no nosso exemplo anterior, como estamos passando apenas uma “string” como parâmetro para a função “call_function”, não é possível para o interpretador garantir que as variáveis e funções estão realmente implementadas no código.
Em geral, quando estamos utilizando ponteiros de função, sabemos quais serão as funções utilizadas pelo nosso programa, e desta forma, podemos definir um “hash” contendo todas as referências para as funções que iremos utilizar, para posteriormente estarmos invocando conforme a necessidade.
#!/usr/bin/perl use strict; my %function_table = ( hello_there => \&hello_there, print_name => \&print_name ); sub hello_there { my $name = shift; print "Hello $name!!\n"; } sub print_name { my $name = shift; print "Nome Informado: $name\n"; } sub call_function { my $function = shift; my $data = shift; print "Inicio\n"; &{$function_table{$function}}($data); print "FIM\n"; } call_function("print_name", "Samuel da Silva Feitosa"); call_function("hello_there", "Samuel");
Veja, que estamos utilizando a diretiva “strict” e que criamos um “hash” chamado “function_table”, onde definimos e referenciamos todas as funções que serão utilizadas pelo nosso programa. Perceba também, que a invocação da função mudou desde o nosso primeiro exemplo. Agora, ao invés de invocarmos diretamente a “string” contendo o nome da função, estamos buscando a referência dela informada no nosso “hash” de funções.
Para finalizar, note que neste exemplo passamos também um parâmetro para nossas funções, e estas manipularam de acordo com sua necessidade.
Este post visa apenas ilustrar o uso de ponteiros de função em PERL, e não cobre suas aplicabilidades. Quem sabe posteriormente eu escreva um pouco sobre isto.