perl - ¿Por qué el uso de la declaración en el sub se aplica globalmente?
module scope (2)
Esto es lo que dice perldoc :
Como el
use
tiene efecto en el momento de la compilación, no respeta el control de flujo ordinario del código que se está compilando. En particular, poner un uso dentro de la rama falsa de un condicional no impide que se procese.
Lamentablemente, no da una explicación de por qué está diseñado de esa manera. Posibles razones podrían ser:
- Perl te da mucha libertad en muchos casos (TIMTOWTDI)
-
use
dentro de una subrutina podría mostrar su intención de que realmente quiera usar un módulo solo en un lugar específico (incluso cuando se cargue globalmente) - Si mueve (re) una determinada subrutina (que contiene un
use
) más adelante, no tiene que preocuparse por eliminar losuse
nouse
de otros lugares, como la parte superior de su secuencia de comandos - ...
A pesar de que estas ideas pueden parecer plausibles, evitaría cargar módulos en subrutinas porque es mucho más claro tenerlos a todos en un solo lugar en lugar de diseminados por todo el lugar.
use WWW::Mechanize;
$mech = new WWW::Mechanize;
$mech->get("http://www.google.com");
$html = HTML::TreeBuilder::XPath->new_from_content($mech->content);
sub test
{
use HTML::TreeBuilder::XPath;
}
El código anterior se compila, por lo que la declaración de use
en el sub
se está aplicando globalmente.
¿Por qué perl
hace esto? No tiene ningún sentido.
use Module;
tiene dos efectos
El primero es cargar el módulo. Obviamente, eso tiene un efecto global. Uno no querría que un módulo se cargue varias veces si lo usa más de otro módulo.
El segundo es llamar al método de import
del módulo. Para la mayoría de los módulos, esto sirve para exportar símbolos al espacio de nombres de la persona que llama para que se puedan llamar esas funciones sin calificarlas con un nombre de paquete completo. Obviamente, esto afecta más que solo un sub, ya que nadie le da a cada subun su propio espacio de nombres. Pero eso depende de ti.
Sin embargo, el método de import
algunos módulos hace algo bastante diferente. Modifican cómo se compila el código en el ámbito léxico en el que está presente la directiva. Estos se llaman pragmas. use strict;
es un ejemplo de uno. Tiene sentido usar estos módulos en un submarino. Uso de use HTML::TreeBuilder::XPath;
en un submarino, sin embargo, no tiene sentido.