El Pragma use subs

Referenciado de Operadores

No es posible referenciar los operadores pre-construidos en Perl:
lhp@nereida:~/Lperl/src$ cat reftooperator.pl
#!/usr/local/bin/perl -w
use strict;

my $a = \&glob;
print $a->('*');
lhp@nereida:~/Lperl/src$ perl reftooperator.pl
Undefined subroutine &main::glob called at reftooperator.pl line 5.

Los nombres de los operadores no están en una tabla de símbolos de un paquete particular.

El Pragma use subs

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



Subsecciones
Casiano Rodríguez León
2009-10-04