Se produce una ambiguedad cuando en un paquete se declara una subrutina cuyo nombre coincide con el de un operador Perl. Si posteriormente dicho nombre es usado sin usar una especificación completa Perl optará por interpretar que se llama al operador Perl y no a la subrutina. Para forzar la llamada a la subrutina se puede usar un ampersand o usar el nombre completo de la subrutina.
El pragma use subs permite una solución alternativa.
Los operadores
originales de Perl serán sustituidos
por nuestras propias versiones en el
ámbito del paquete. En el siguiente programa
sustituímos glob
en el ámbito del paquete
Glob::Regexp
:
lhp@nereida:~/Lperl/src$ cat -n usesubs.pl 1 #!/usr/local/bin/perl -w 2 package Glob::Regexp; 3 use strict; 4 use subs qw(glob); 5 6 sub glob { 7 my $regexp = shift; 8 9 opendir my $DIR, "." or die "$!"; 10 my @files = grep /$regexp/, readdir $DIR; 11 close($DIR); 12 return @files; 13 } 14 15 sub tutu { 16 my @a = glob('^.[cd][ba].*\.pl'); # LLamada al nuevo glob 17 local $" = "\n"; 18 my @b = <^.[cd][ba].*\.pl>; # El diamante es una llamada a glob 19 return <<"EOI"; 20 ---glob('^.[cd][ba].*\.pl')--- 21 @a 22 ---<^.[cd][ba].*\.pl>--- 23 @b 24 EOI 25 } 26 27 package main; 28 29 sub tutu { 30 my @a = glob('^.[cd][ba].*\.pl'); 31 local $" = "\n"; 32 return "@a\n"; 33 } 34 35 print Glob::Regexp::tutu; 36 print "---------main-----------\n"; 37 print tutu;Al ejecutar el programa vemos que la subrutina
Glob::Regexp::tutu
(llamada desde la línea 35) usa la nueva
versión de glob
mientras que los usos de glob
dentro del paquete main
usan la versión original.
La ejecución también muestra que el uso de diamantes
en ''modo directorio'' como en <^.[cd][ba].*\.pl>
implica una llamada implícita a glob .
lhp@nereida:~/Lperl/src$ usesubs.pl ---glob('^.[cd][ba].*.pl')--- idbetcurly.pl pcap.pl scalar_sets.pl scalar_sets2.pl sdbm.pl sdbm2.pl ---<^.[cd][ba].*.pl>--- idbetcurly.pl pcap.pl scalar_sets.pl scalar_sets2.pl sdbm.pl sdbm2.pl ---------main-----------
Casiano Rodríguez León