/ / Cómo llamar a un módulo sub dentro de otro módulo sub en Perl - perl

Cómo llamar a un módulo sub dentro de otro módulo sub en Perl - perl

He creado módulos Perl bajo /my_project/ABC/. los ABC La carpeta contiene tres módulos de subrutina: Build.pm, Config.pmy Operation.pm. Hay una subrutina común en Operation.pm a la que necesito acceder Config.pm, pero cuando lo intenté lanzo

"configureTheRepository" no es exportado por el módulo ABC :: Config`.

Aquí está la pila de llamadas.

Operation.pm

    package ABC::Operation;

use strict;
use warnings;

use Term::ANSIColor qw(:constants);
use File::Basename qw(dirname);
use Exporter qw(import);
use Term::ANSIColor qw( colored );
use Data::Dumper qw(Dumper);
use JSON::PP;
use File::Basename qw(dirname);
use Cwd  qw(abs_path);
use ABC::Config qw(configureTheRepository);

our @EXPORT = qw(commonFunc)

sub commonFunc{
#handle logic
}
1;

Config.pm

    package ABC::Config;

use strict;
use warnings;

use Term::ANSIColor qw(:constants);
use File::Basename qw(dirname);
use Exporter qw(import);
use Cwd  qw(abs_path);
use Cwd  qw(abs_path);
use ABC::Operation qw(commonFunc); #Compilation failed when i insert this line.if i removed this my script will execute and but in runtime throws undefined commonFunc.

our @EXPORT = qw(configureTheRepository);

sub configureTheRepository{
#handle logic
}

1;

Por favor, hágame saber dónde cometí el error.

Respuestas

3 para la respuesta № 1

Hay una dependencia circular. use declaraciones se hacen en tiempo de compilación. Eso significa antes de ejecutar cualquier código real. Entonces, cuando comienzas tu programa, y ​​lo primero que hace es entrar en ABC::Operation, sucederá lo siguiente:

  • escanear ABC :: Operación para use declaraciones
  • Término de carga :: ANSIColor
    • el análisis cambia a Término :: ANSIColor
    • término de escaneo :: ANSIColor para use declaraciones ...
  • el análisis vuelve a ABC :: Operación
  • cargar archivo :: Basename
    • el análisis cambia a File :: Basename
    • Archivo de escaneo :: Basename
  • el análisis vuelve a ABC :: Operación
  • ... un par más de esos
  • cargar ABC :: Config
    • el análisis cambia a ABC :: Config
    • escanear ABC :: Config para use declaraciones ...
  • analizando a las brujas de vuelta a ABC :: Operation
    • import cosas de Term :: ANSIColor, File :: Basename, Exporter y Cwd; estos no se vuelven a cargar porque Perl ya los cargó antes. Solo importa los símbolos en el espacio de nombres ABC :: Config actual
    • import la función commonFunc de ABC :: Config; nuevamente, esto también ya se ha cargado, por lo que no lo vuelve a cargar
    • arroja un error porque en este punto, ABC :: Config no ha finalizado el análisis y aún no exporta un commonFunc símbolo

Esto es un poco confuso, pero es una señal de que su arquitectura está rota. Si las cosas son comunes, seguramente pueden estar en un paquete común. Pero ese paquete común no poder usa cualquier cosa que lo use. Si ese es el caso, lo que sea que lo esté usando también se vuelve común por definición.

La solución es repensar qué funciones vandónde. Encuentre las partes más pequeñas posibles y póngalas en un paquete. Esas son las cosas que comparte cualquier otro paquete. Luego, úselo donde sea necesario. Las siguientes cosas que usan esto no deberían "interponerse entre sí. Solo el último nivel debería combinarlas todas. El árbol de dependencia se llama árbol por una razón. Tener un círculo allí no puede funcionar".