modules mcpan library perl perl-module

library - perl mcpan



export vs export_ok en perl (2)

No puedo entender cuál es el caso de diferencia / uso de EXPORT_OK frente a EXPORT .
La mayoría de los recursos menciona algo en las líneas de:

@Export permite exportar las funciones y variables de los módulos al espacio de nombres del usuario utilizando el método de importación estándar. De esta forma, no es necesario crear los objetos para que los módulos accedan a sus miembros.
@EXPORT_OK exporta símbolos a petición para la lista selectiva de símbolos (subrutinas y variables) del módulo.

Pero realmente no veo la diferencia / significado aquí.
¿Puede alguien proporcionar un pequeño ejemplo fundamental de la diferencia / uso de estos 2 símbolos?


Del fino manual del exportador :

  • use YourModule;
    Esto importa todos los símbolos de @EXPORT de @EXPORT en el espacio de nombres de la declaración de uso .
  • use YourModule ();
    Esto hace que perl cargue su módulo pero no importa ningún símbolo.
  • use YourModule qw(...);
    Esto solo importa los símbolos enumerados por la persona que llama en su espacio de nombre. Todos los símbolos listados deben estar en su @EXPORT o @EXPORT_OK , de lo contrario, se produce un error. Las funciones avanzadas de exportación de Exporter se acceden así, pero con entradas de lista que son sintácticamente distintas de los nombres de símbolos.

Por lo tanto, si usa @EXPORT y alguien hace el use YourModule; habitual de use YourModule; , entonces acaba de contaminar su espacio de nombres con todo en @EXPORT . Pero, si usa @EXPORT_OK , tienen que pedir específicamente que se importen elementos para que la persona que usa su módulo tenga control sobre lo que sucede con su espacio de nombres.

La diferencia es realmente una cuestión de quién controla qué entra en el espacio de nombres de r de use : si usa @EXPORT entonces el módulo que se use d lo hace, si usa @EXPORT_OK entonces el código que realiza la importación controla su propio espacio de nombres.

Por supuesto, siempre puedes decir use Whatever(); para evitar que los módulos descorteses contaminen tu espacio de nombres, pero eso es feo y no deberías tener que preocuparte por el código grosero que quiere garabatear en todo tu espacio de nombres.


Digamos que tengo un paquete MyPackage que usa @EXPORT .

#this is MyPackage.pm package MyPackage; @EXPORT = qw(do_awesome_thing); sub do_awesome_thing { ... } sub be_awesome { ... }

Ahora, cuando uso MyPackage en mi código,

#this is myscript.pl use MyPackage; do_awesome_thing(); #works be_awesome(); #doesn''t work MyPackage::be_awesome(); #works

do_awesome_thing se exporta automáticamente a mi código desde MyPackage , sin que yo tenga que decir "dame esto". be_awesome no se exporta (y tampoco se exportará con @EXPORT_OK , solo le @EXPORT_OK esa parte para que @EXPORT_OK lo que "exportar" nos brinda).

Por otro lado, si tengo un paquete MyOtherPackage que usa @EXPORT_OK ,

#this is MyOtherPackage.pm package MyOtherPackage; @EXPORT_OK = qw(do_awesome_thing); sub do_awesome_thing { ... } sub be_awesome { ... }

y luego prueba

#this is mynewscript.pl use MyOtherPackage; do_awesome_thing(); #doesn''t work MyOtherPackage::do_awesome_thing(); #works, as always

la línea que llama a do_awesome_thing directamente no funcionará. Esto se debe a que al poner algo en @EXPORT_OK dice " @EXPORT_OK a mis usuarios solo si lo piden". Como acabamos de decir, use MyOtherPackage sin pedir explícitamente que se importe aquí do_awesome_thing , no se importa y solo se puede acceder especificando el nombre del paquete.

La forma en que pides que se importe do_awesome_thing es decir use MyOtherPackage qw(do_awesome_thing) en la segunda línea de mynewscript.pl anterior. Esto dice importar ese módulo y hacer do_awesome_thing disponible directamente. Después de eso, la cuarta línea en mynewscript.pl arriba comenzará a funcionar.

Tenga en cuenta que el usuario puede especificar el use MyPackage qw(do_awesome_thing) con el primer paquete también, y en ese caso, cualquier otra cosa en la lista @EXPORT no se exportará, solo do_awesome_thing será. Entonces, a excepción del caso de use PackageName; predeterminado use PackageName; , @EXPORT y @EXPORT_OK comportan de manera similar. En el caso predeterminado, cualquier elemento de @EXPORT se @EXPORT automáticamente al script del usuario, mientras que @EXPORT_OK es más cortés y no exporta nada.