in reply to Best way to pass variables?

You don't have to declare the variable where you assign it. You can declare it above, so that each block is using the same $response, and it's available outside them:
die "Required argument missing!\n" unless ($ARGV[0]); my $response; if ($ARGV[0] =~ /Hello/i) { $response = "Hello to you.\n"; }else{ $response = "Huh?\n"; } print $response;
If by "global" you mean a lexical outside of any enclosing block (which is not the customary meaning), and you have some aversion to having such a thing, just wrap a block around the area where it's used:
die "Required argument missing!\n" unless ($ARGV[0]); { #scoping block my $response; if ($ARGV[0] =~ /Hello/i) { $response = "Hello to you.\n"; }else{ $response = "Huh?\n"; } print $response; }

The PerlMonk tr/// Advocate

Replies are listed 'Best First'.
Re: Re: Best way to pass variables?
by Elijah (Hermit) on Mar 05, 2004 at 22:07 UTC
    Yeah I have used the incomplete type declerations (my $response;) for this in the past which to me was the best way but it was still used in a global sense.

    I was just wanting to know if there was a better way that was used or could be used. I usualy just declare all my global variables together first. my($response, $var2, $var3, $var4); etc....

    So it would usually look like such in one of my scripts:

    #!/usr/bin/perl -w use strict; my($response); die "Required argument missing!\n" unless ($ARGV[0]); if ($ARGV[0] =~ /Hello/i) { $response = "Hello to you.\n"; }else{ $response = "Huh?\n"; } print $response;

    This interest was sparked because in other language I code in I usually try to "limit the scope" of my variables and try not to use global variables too much. In some languages this is looked down upon and can cause problems.

      My 2nd example showed how you can limit the scope of the lexical variable: just wrap the desired area in a block. The variable will exist only within that block. That is the "better way" you were looking for.

      You should note that your use of "global" is not the same as Perl's. Variables that are declared with my are never globals. They are lexicals, scoped either by an enclosing block, or by the file if there is no enclosing block. Globals, on the other hand, are associated with packages and have entries in symbol tables. It is this type of global that perl was warning you about when it complained about your print $response statement. Because you had not declared the variable as lexical in the enclosing scope, $response was presumed to be $main::response (that is, the global variable named $response within the main:: package).


      The PerlMonk tr/// Advocate

      Here's an option that uses Roy's scoping block and your possibly lengthy list of global variables.

      You create a hash reference inside the scoping block: it is not visible to any code outside the block including any subroutines (one of the main problems with globals). You then let Perl autovivify your $response, $var2, etc. as keys in the hashref: all of these will go out-of-scope with the hashref (sorry, that's probably obvious).

      You can pass the hashref to subroutines that need any of the global variables: that's good for (a) performance because you're only passing a single scalar and (b) good for maintenance because you don't need to align lengthy lists of arguments between caller and callee. Furthermore, because it's a reference you don't need to return it.

      The only cautionary note I'd raise is don't trap the hashref in a closure: that will have a high probability of causing you grief.

      Here's a fragmented example:

      #!/usr/bin/perl ... { # scoping block my $rh_vars = {}; if (...) { $rh_vars->{response} = 'whatever'; if (...) { $rh_vars->{var2} = 'something'; } func($rh_vars); } print $rh_vars->{response}; } # $rh_vars out-of-scope here ... exit 0; sub func { my $rh_vars = shift; if (exists $rh_vars->{var2}) { # do something with "var2" } }

      I've kept this example code short and skeletal. I'll happily expand or clarify any points if necessary.

      As an aside, you may notice that this code is halfway down the road to being object-oriented: you've encapsulated and hidden your data in the hashref which is acting like a light-weight object (unblessed - no inheritance).

      PN5