http://www.perlmonks.org?node_id=987025

bebe has asked for the wisdom of the Perl Monks concerning the following question:

Hi everyone,
I'm new to perl and I keep getting the following error. Any idea how I can get rid of it?
"Global symbol "@state" requires explicit package name"


use threads::shared;
use strict;
use warnings;


my $tmp=meow();
my $state = &make_shared_array();

for (my $i=0 ; $i<2; $i++){
for (my $j=0; $j<6; $j++){
print "$state[$i][$j] \n";
}
}


my @array = ();
#for(my $i=0; $i<222; $i++){
for (my $j=0; $j<222; $j++){
$array[$j] = $state[1][$j];
}

if ($array[0] == $state[1][0]){
print " array[0] = $array[1] \n";
}
sub meow {
my $i = 0;
my $j = 1;
my @p = ("grey" , "striped" , "purrr", "cutest_kitty" , "meowing_kitty", "the_lord_of_the_cats");
my @k = ("smart_kitty" , "striped_sweety" , "purrr", "meowing_poes" , "social_kitty", "the_lord_of_the_poezen");

for (my $f=0; $f<6 ; $f++) {
push(@{$state[$i]}, $p[$f]);
push(@{$state[$j]}, $k[$f]);
}

Replies are listed 'Best First'.
Re: Global symbol requires explicit package name
by cheekuperl (Monk) on Aug 13, 2012 at 05:23 UTC
    You need to declare @state too since use strict is in action.

      but I thought I have already declared @state? I declared it as a shared variable... if I declare it again in the subs, I won't be using the same shared variable "state" anymore, right?
      I'm a little bit confused... I know if I comment out "strict" it will work... but where else do you suggest I declare state?
      Thank you very much
        No you did not declare @state. You declared $state which is an entirely different variable. Most probably make_shared_array() returns an array reference to you. Check the documentation.

        And BTW, dont call it as &make_shared_array(): that is very "old" style and it has side-effects you probably do not know about.

        Deleting use strict is not a good idea. It pointed an error out to you. Removing use strict does not make the error go away, only the error message, the error being that @state is not the shared variable you think it is, a very fundamental error.

        Update: A rather handy trick you can try is using Data::Dumper to inspect your arrays and hashes. Then you do not have to write all these for loops with nothing but a print inside.

        CountZero

        A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

        My blog: Imperial Deltronics

        You declared $state. If it contains an array reference, you have to dereference it.


        Improve your skills with Modern Perl: the free book.

Re: Global symbol requires explicit package name
by 2teez (Vicar) on Aug 13, 2012 at 06:48 UTC
    Hi,

    Any idea how I can get rid of it? "Global symbol "@state" requires explicit package name"
    There are several things not quite correct with your script.

    • Used an array reference variable $state in your meow() subroutine yet that was not declared at all,
    • Since, from the use of the push function is obvious you really want to build an array of array, yet your construction was not also right
    • It's also best practice to always explicitly " return " from a subroutine in Perl. Though some may not agree with that. But you need it.
    When all that was "taken" out of the way. There is still a " scalar" variable called $state though declared, but then used as an Array of Array!!!
    Though there is a subroutine called "&make_shared_array();" which was not showed in your script. And you shouldn't call Perl 5 subroutine as Perl 4, expect in some other cases, where subroutine refrenece is needed. Even in that you can still come around it!
    How I got rig of the error message:
    To make the script work. Corrected all mention above. And then commented "OUT" this line my $state = &make_shared_array(); since the subroutine "make_shared_array()" was not given, then in the PLACE of the INTENDED AoA variable $state, I used the variable "$tmp".
    I don't know if that is permited. If not you might have to check that out and fix the variable $state that is "supposed" to be used. But am sure, the usage should be in the way I used $tmp.
    But really, really, I don't know what the subroutine " make_shared_array()" returns.

    Modified script:
    #!/usr/bin/perl use warnings; use strict; use threads::shared; my $tmp = meow(); #my $state = &make_shared_array(); for ( my $i = 0 ; $i < 2 ; $i++ ) { for ( my $j = 0 ; $j < 6 ; $j++ ) { print "$tmp->[$i][$j] \n"; } } my @array = (); #for(my $i=0; $i<222; $i++){ for ( my $j = 0 ; $j < 222 ; $j++ ) { $array[$j] = $tmp->[1][$j]; } if ( $array[0] eq $tmp->[1][0] ) { print " array[0] eq $array[1] \n"; } sub meow { my $i = 0; my $j = 1; my $state = []; ### added Array Ref my @p = ( "grey", "striped", "purrr", "cutest_kitty", "meowing_kitty", "the_lord_of_the_cats" ); my @k = ( "smart_kitty", "striped_sweety", "purrr", "meowing_poes", "social_kitty", "the_lord_of_the_poezen" ); for ( my $f = 0 ; $f < 6 ; $f++ ) { push( @{ $state->[$i] }, $p[$f] ); ### always remember the +arrow -> push( @{ $state->[$j] }, $k[$f] ); ### always remember the +arrow -> } return $state; ### added explict return }
    You also do not want to use C for loop in Perl. Though it works, but Let make Perl speak Perl not other language.:)
    You might have to check out the following for detailed Info:
    perldoc perldsc,
    perldoc perllol,
    perldoc perldata,
    perldoc perlref

    Hope this helps.

      Thank you so much for your detailed reply. Sorry I left out this subroutine.
      The reason I'm using this is to share the array of arrays. I'm very new with perl how do you suggest I share this array of array instead of using this subroutine?


      sub make_shared_array {
      my $a = &share([]);
      for (my $i = 0;$i <6 ; ++$i) {
      my $row = &share([]);
      $a->[$i] = $row;
      }
      return $a;
      }
      Thank you so much!!! I greatly appreciate all your help
        hi,

        how do you suggest I share this array of array instead of using this subroutine?

        from your Code:
        What is &share([]);?
        Are you trying to call a Subroutine reference within another subroutine, then assign to a scalar variable? Really, I don't know what you want to achieve here Please.
        You probably have to include all the subroutine you are trying to use.

      Thank you so much for your advice... I tried your solution! it works and I no longer get the Global symbol ... error. :-)
      However I now get a new error message:
      Use of uninitialized value in string eq at sharingpoes.pl line 30. Use of uninitialized value in string eq at sharingpoes.pl line 30.
      I'm the cutest kitty ever
      Use of uninitialized value in concatenation (.) or string at sharingpoes.pl line 31.
      array[0] =


      if ( $array[0] eq $tmp->[1][0] ) { #line 30
      print " array[0] eq $array[1] \n"; # line 31
      }

      Thank you so very much!

Re: Global symbol requires explicit package name
by bulk88 (Priest) on Aug 13, 2012 at 05:25 UTC
    You used "strict" and it caught you. The docs for the error are here strict vars.

      Thanks a lot for the link. I understand the error now, but I still have no idea how to handle this since "state" is a shared variable. do you have any idea?

      Thank you very much

Re: Global symbol requires explicit package name
by aitap (Curate) on Aug 13, 2012 at 07:35 UTC

    Try printing $state->[$i][$j]." \n" instead of print "$state[$i][$j] \n";. What line does that error message relate to? See perldoc perlreftut for more info.

    Edit: well, I was late with this.

    Sorry if my advice was wrong.

      Thank you so much for your reply. I ended up commenting out this print statement for now since I don't seem to be able to get this program to work. I now get this new error
      "se of uninitialized value in string eq at sharingpoes.pl line 30.
      Use of uninitialized value in string eq at sharingpoes.pl line 30.
      I'm the cutest kitty ever
      Use of uninitialized value in concatenation (.) or string at sharingpoes.pl line 31.
      array[0] =
      " any idea how I can fix this? Thank you so much!!!

        Try running your code in the debugger. Use n and x commands.

        I also tried to look for line 30 in the code you posted, but couldn't find any eq in it. Can you post a minimal code example, properly formatted?

        Sorry if my advice was wrong.