in reply to Understanding why strict prevents a use of local

localizing a variable makes a global variable which has a copy for you. It's like a sort-of-but-not-quite lexical. Hence, strict sees local as a global and complains.

Use my instead.

------
We are the carpenters and bricklayers of the Information Age.

Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.

  • Comment on Re: Understanding why strict prevents a use of local

Replies are listed 'Best First'.
Re: Re: Understanding why strict prevents a use of local
by c (Hermit) on Oct 19, 2001 at 22:54 UTC
    Using 'my' in this situation though would require that i pass that value on to the next sub routine wouldnt it? for example:

    #!/usr/bin/perl -w use strict; &one; sub one { my $a = "hello"; &two($a); } sub two { my $a = shift; print $a; }

    i ask simply because this whole exercise is being done for a rather lengthy script i have that makes use of several subroutines, all called from one main sub. i end up passing a fairly long group of variables to each of the other subs

    sub execute { &ccCopy($source,$destination,$host,$error); } sub ccCopy { my $source = shift; my $destination = shift; my $host = shift; my $error = shift; }

    this works, but i was hoping to use 'local' two get rid of these extra lines and try to streamline a bit.

    humbly -c

      The reason that local causes strict to complain is that local does not declare global variables (strict only complains about global variables if you haven't declared them). The purpose of local is to temporarily hide the original value of the global, so that you don't accidentally overwrite a value that the rest of your program is using. Basically, letting you use a global variable as if it were lexical. (Sort of.)

      However, that's not what you want to do. You actually want to access the global value of the variable but you want to declare it, so that strict stops complaining. To do that, remove the locals, and add an our (or use vars for < 5.6) to the beginning of the program:

      #!/usr/bin/perl -w use strict; our $i; # Predeclare $i as a global, so # that strict doesn't complain. my @array = qw(one two three); &one; sub one { foreach $i (@array) { &two; } } sub two { print "$i\n"; }

      That said, global variables are usually a bad idea, especially in large (or "lengthy") programs. You should probably go with dragonchild's hash suggestion, or something.

      bbfu
      Seasons don't fear The Reaper.
      Nor do the wind, the sun, and the rain.
      We can be like they are.

      Why not try something like:
      sub execute { my %argsHash = ( Source => $source, Dest => $destination, Host => $host, Error => $error, ); &ccCopy(\%argsHash); } sub ccCopy { my $args = shift; print "Copy: $args->{Source} to $args->{Dest}\n"; }
      That will do two things:
      1. Clean up your messy-looking code
      2. Make it so you stay out of procedural messes by fooling with global variables. (They're sorta like matches, but for big kids. You still don't want to play with them.)

      ------
      We are the carpenters and bricklayers of the Information Age.

      Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.

        i like this solution, however can i add to the hash reference being passed to each subroutine? i ask because my subroutines add to the information being handed down with each nesting:

        #!/usr/bin/perl -w use strict; my $source = "tftp"; my $destination = "run"; &first; sub first { my %argsHash = ( Source => $source, Destination => $destination, ); &second(\%argsHash); } sub second { my $args = shift; my $error = "problems!"; print "This works, but i need to pass the error value to the third subroutine, in addition to $args->{Source} and $args->{Destination}\n"; &third(); }

        its here that i get confused. not only do i need to pass the existing value of $args to the third subroutine, but i also need to pass the value of $error as well. i've tried a little experimenting with &third(\$args); and although its passed, its passed as a scalar rather than a hash it seems. i see that i can add the value of $error within the second subroutine, such as:

        $args->{Error} = $error;

        but i'm stuck on how to pass this new hash to the next subroutine.

        humbly -c

      Hi c,

      In my opinion your comment that this "is being done for a rather lengthy script" says to me that you want to avoid globals at all cost. The comments and snippits of advice of our fellow monks in this case are excellent and will work perfectly fine for you. But just in case you were looking for yet another way to do it...

      --
      http://www.nule.org