简体   繁体   中英

Access “external” Perl Array from “BEGIN” Block/Package

Below is a simplified version of a perl script I am trying to modify:

use MODULE_1 ;
use MODULE_2 ;
use vars qw(%ARR  $VarZZ) ;

sub A {
    # Somestuff

    # Call to Sub B
    B() ;
    # Call to Sub C
    C() ;
}

BEGIN {
    package XYZ ;
    use vars qw($VarYY  $VarXX) ;
    # MISC SUBS HERE
    # end of package XYZ
}

sub B {
    # Somestuff
}

sub C {
    # Somestuff to set %ARR
}

# Call to Sub A
A() ;

My issue is that I will like to access %ARR within the package XYZ BEGIN block but keep getting error messages saying I need to define %ARR ("requires explicit package name")

I have tried, trying to copy a similar example within the block, $main::ARR{index} but failed so far.

I assume it may be because %ARR isn't set when that block is begin evaluated and that I need to call "sub C" perhaps but &main::C(); seems to be failing as well.

How can I access this array there?

I have looked at: Perl's main package - block syntax - pragmas and BEGIN/END blocks which seems to be addressing similar themes but struggling to properly understand the answers

** EDIT **

Expanded skeleton script showing some attempts at moving forward:

use MODULE_1 ;
use MODULE_2 ;
use vars qw(%ARR  $VarZZ) ;

sub A {
    # Somestuff

    # Call to Sub B
    B() ;
    # Call to Sub C
    C() ;
    # Call to Sub E
    E() ;
}

sub E {
    # Call to Package XYZ subs
}

BEGIN {
    package XYZ ;
    use vars qw($VarYY  $VarXX %ARR) ;

    # I tried to Call to Sub C and load a local version of %ARR
    #
    # This fails with "Undefined subroutine &main::C" error
    &main::C() ;
    #
    # We never get here so not sure if correct
    %ARR = &main::ARR ;


    # MISC SUBS HERE
        sub X {
            # Call to Sub D
            &main::D() ;
        }
    # end of package XYZ
}

sub B {
    # Somestuff
}

sub C {
    # Somestuff to set %ARR
}
sub D {
    # Somestuff
}

# Call to Sub A
A() ;

Note the the call to &main::E() works when called within the Subs in Package XYZ but both this and &main::C() fail when running free standing. Perhaps the free standing call is done at complile time before the subs are defined.

BTW, I tried the our definition but getting a 502 error: Nginx Debug Log

Perhaps this is because the array is not available?

%main:ARR or $main::ARR{index} are correct for the code skeleton you have provided (well, anything is correct because you haven't said use strict , but anyway ...). Is it possible that main is not the correct namespace (ie, is there some pacakge statement that precedes use vars ... ) ?

In any case, you can workaround this issue with the our keyword. If you declare it at the top level, it will have scope throughout the rest of the file:

package ABC;
our %ARR;      # %ABC::ARR

sub foo {
   $ARR{"key"} = "value";  # %ABC::ARR
}

{   # "BEGIN" optional
    package XYZ;
    our %Hash;    # %XYZ::Hash
    sub bar {
        my $key1 = $Hash{"key1"};  # %XYZ::Hash
        my $val1 = $ARR{$key1};    # %ABC::ARR
        $ARR{$val1} = $key1;
    }
}

...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM